MDL-14200 "Add group and course averages" added extra rows to the end of the table in quiz overview report also MDL-14187 "Improve tablelib - improve api and add functionality to download table contents in a variety of formats - XLS, ODS and CSV" implemented the first of my proposals for improving tablelib. Added a extra method to use keyed arrays to add a row to a table. Seems obvious that this is an improvement to tablelib and it is an addition to the API so won't affect existing code.

This commit is contained in:
jamiesensei
2008-05-15 12:25:04 +00:00
parent 316d595389
commit 5746826364
3 changed files with 141 additions and 29 deletions
+21
View File
@@ -774,6 +774,27 @@ class flexible_table {
}
$this->data[] = NULL;
}
/**
* Add a row of data to the table. This function takes an array with
* column names as keys.
* It ignores any elements with keys that are not defined as columns. It
* puts in empty strings into the row when there is no element in the passed
* array corresponding to a column in the table. It puts the row elements in
* the proper order.
* @param $rowwithkeys array
*
*/
function add_data_keyed($rowwithkeys){
foreach (array_keys($this->columns) as $column){
if (isset($rowwithkeys[$column])){
$row [] = $rowwithkeys[$column];
} else {
$row[] ='';
}
}
$this->add_data($row);
}
}
+49 -27
View File
@@ -44,10 +44,6 @@ class quiz_report extends quiz_default_report {
//twice.
}
// Set of format options for teacher-created content, for example overall feedback.
$nocleanformatoptions = new stdClass;
$nocleanformatoptions->noclean = true;
// Work out some display options - whether there is feedback, and whether scores should be shown.
$hasfeedback = quiz_has_feedback($quiz->id) && $quiz->grade > 1.e-7 && $quiz->sumgrades > 1.e-7;
$fakeattempt = new stdClass();
@@ -197,6 +193,8 @@ class quiz_report extends quiz_default_report {
$table->column_suppress('fullname');
$table->column_class('picture', 'picture');
$table->column_class('fullname', 'bold');
$table->column_class('sumgrades', 'bold');
$table->set_attribute('cellspacing', '0');
$table->set_attribute('id', 'attempts');
@@ -293,17 +291,15 @@ class quiz_report extends quiz_default_report {
echo implode("\t", $headers)." \n";
}
// Get users with quiz attempt capability 'students'.
// don't need to do this expensive call if we are listing all attempts though.
if ( $attemptsmode != QUIZ_REPORT_ATTEMPTS_ALL ) {
if (empty($currentgroup)) {
// all users who can attempt quizzes
$allowed = join(',',array_keys(get_users_by_capability($context, 'mod/quiz:attempt','','','','','','',false)));
} else {
// all users who can attempt quizzes and who are in the currently selected group
$allowed = join(',',array_keys(get_users_by_capability($context, 'mod/quiz:attempt','','','','',$currentgroup,'',false)));
}
$students = join(',',array_keys(get_users_by_capability($context, 'mod/quiz:attempt','','','','','','',false)));
if (empty($currentgroup)) {
// all users who can attempt quizzes
$groupstudents = '';
$allowed = $students;
} else {
// all users who can attempt quizzes and who are in the currently selected group
$groupstudents = join(',',array_keys(get_users_by_capability($context, 'mod/quiz:attempt','','','','',$currentgroup,'',false)));
$allowed = $groupstudents;
}
// Construct the SQL
@@ -336,6 +332,7 @@ class quiz_report extends quiz_default_report {
$where = ' WHERE u.id IN (' .$allowed. ') AND (qa.preview = 0 OR qa.preview IS NULL)';
break;
}
$countsql = 'SELECT COUNT(DISTINCT('.sql_concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).')) '.$from.$where;
@@ -390,14 +387,6 @@ class quiz_report extends quiz_default_report {
$table->pagesize($pagesize, $total);
}
// If there is feedback, include it in the query.
if ($hasfeedback) {
$factor = $quiz->grade/$quiz->sumgrades;
$select .= ', qf.feedbacktext ';
$from .= " LEFT JOIN {$CFG->prefix}quiz_feedback qf ON " .
"qf.quizid = $quiz->id AND qf.mingrade <= qa.sumgrades * $factor AND qa.sumgrades * $factor < qf.maxgrade";
}
// Fetch the attempts
if (!$download) {
$attempts = get_records_sql($select.$from.$where.$sort,
@@ -523,7 +512,7 @@ class quiz_report extends quiz_default_report {
// Feedback column.
if ($hasfeedback) {
if ($attempt->timefinish) {
$row[] = format_text($attempt->feedbacktext, FORMAT_MOODLE, $nocleanformatoptions);
$row[] = quiz_report_feedback_for_grade(quiz_rescale_grade($attempt->sumgrades, $quiz), $quiz->id);
} else {
$row[] = '-';
}
@@ -542,6 +531,37 @@ class quiz_report extends quiz_default_report {
echo $text." \n";
}
}
//end of adding data from attempts data to table / download
//now add averages :
if (!$download && $attempts){
$averagesql = "SELECT AVG(qg.grade) AS grade " .
"FROM {$CFG->prefix}quiz_grades qg " .
"WHERE quiz=".$quiz->id;
$table->add_separator();
if ($groupstudents){
$groupaveragesql = $averagesql." AND qg.userid IN ($groupstudents)";
$groupaverage = get_record_sql($groupaveragesql);
$groupaveragerow = array('fullname' => get_string('groupavg', 'grades'),
'sumgrades' => round($groupaverage->grade, $quiz->decimalpoints),
'feedbacktext'=> quiz_report_feedback_for_grade($groupaverage->grade, $quiz->id));
if($detailedmarks && $qmfilter) {
$avggradebyq = quiz_get_average_grade_for_questions($quiz, $groupstudents);
$groupaveragerow += quiz_format_average_grade_for_questions($avggradebyq, $questions, $quiz, $download);
}
$table->add_data_keyed($groupaveragerow);
}
$overallaverage = get_record_sql($averagesql." AND qg.userid IN ($students)");
$overallaveragerow = array('fullname' => get_string('overallaverage', 'grades'),
'sumgrades' => round($overallaverage->grade, $quiz->decimalpoints),
'feedbacktext'=> quiz_report_feedback_for_grade($overallaverage->grade, $quiz->id));
if($detailedmarks && $qmfilter) {
$avggradebyq = quiz_get_average_grade_for_questions($quiz, $students);
$overallaveragerow += quiz_format_average_grade_for_questions($avggradebyq, $questions, $quiz, $download);
}
$table->add_data_keyed($overallaveragerow);
}
if (!$download) {
// Start form
echo '<div id="tablecontainer">';
@@ -604,9 +624,11 @@ class quiz_report extends quiz_default_report {
// Print display options
$mform->set_data($displayoptions +compact('detailedmarks', 'pagesize'));
$mform->display();
$imageurl = $CFG->wwwroot.'/mod/quiz/report/overview/overviewgraph.php?id='.$quiz->id;
print_heading(get_string('overviewreportgraph', 'quiz_overview'));
echo '<div class="mdl-align"><img src="'.$imageurl.'" alt="'.get_string('overviewreportgraph', 'quiz_overview').'" /></div>';
if ($attempts){
$imageurl = $CFG->wwwroot.'/mod/quiz/report/overview/overviewgraph.php?id='.$quiz->id;
print_heading(get_string('overviewreportgraph', 'quiz_overview'));
echo '<div class="mdl-align"><img src="'.$imageurl.'" alt="'.get_string('overviewreportgraph', 'quiz_overview').'" /></div>';
}
}
return true;
}
+71 -2
View File
@@ -36,6 +36,44 @@ function quiz_get_newgraded_states($attemptids, $idxattemptq = true){
return array();
}
}
function quiz_get_average_grade_for_questions($quiz, $userids){
global $CFG;
$gradedevents = QUESTION_EVENTGRADE.','.
QUESTION_EVENTCLOSEANDGRADE.','.
QUESTION_EVENTMANUALGRADE;
$qmfilter = quiz_report_qm_filter_subselect($quiz, 'qa.userid');
$questionavgssql = "SELECT qs.question, AVG(qs.grade) FROM " .
"{$CFG->prefix}question_sessions qns, " .
"{$CFG->prefix}quiz_attempts qa, " .
"{$CFG->prefix}question_states qs " .
"WHERE qns.attemptid = qa.uniqueid AND " .
"qa.quiz = {$quiz->id} AND " .
($qmfilter?$qmfilter.' AND ':'').
"qa.userid IN ({$userids}) AND " .
"qs.event IN ($gradedevents) AND ".
"qns.newgraded = qs.id GROUP BY qs.question";
return get_records_sql_menu($questionavgssql);
}
function quiz_format_average_grade_for_questions($avggradebyq, $questions, $quiz, $download){
$row = array();
if (!$avggradebyq){
$avggradebyq = array();
}
foreach(array_keys($questions) as $questionid) {
if (isset($avggradebyq[$questionid])){
$grade = $avggradebyq[$questionid];
$grade = quiz_rescale_grade($grade, $quiz);
} else {
$grade = '--';
}
if (!$download) {
$grade = $grade.'/'.quiz_rescale_grade($questions[$questionid]->grade, $quiz);
}
$row['$'.$questionid]= $grade;
}
return $row;
}
/**
* Load the question data necessary in the reports.
* - Remove description questions.
@@ -78,7 +116,7 @@ function quiz_report_load_questions($quiz){
* one attempt that will be graded for each user. Or return
* empty string if all attempts contribute to final grade.
*/
function quiz_report_qm_filter_subselect($quiz){
function quiz_report_qm_filter_subselect($quiz, $useridsql = 'u.id'){
global $CFG;
if ($quiz->attempts == 1) {//only one attempt allowed on this quiz
return '';
@@ -100,7 +138,7 @@ function quiz_report_qm_filter_subselect($quiz){
}
if ($qmfilterattempts){
$qmsubselect = "(SELECT id FROM {$CFG->prefix}quiz_attempts " .
"WHERE quiz = {$quiz->id} AND u.id = userid " .
"WHERE quiz = {$quiz->id} AND $useridsql = userid " .
"ORDER BY $qmorderby LIMIT 1)=qa.id";
} else {
$qmsubselect = '';
@@ -141,4 +179,35 @@ function quiz_report_highlighting_grading_method($quiz, $qmsubselect, $qmfilter)
('<span class="highlight">'.quiz_get_grading_option_name($quiz->grademethod).'</span>'))."</p>";
}
}
/**
* Get the feedback text for a grade on this quiz. The feedback is
* processed ready for display.
*
* @param float $grade a grade on this quiz.
* @param integer $quizid the id of the quiz object.
* @return string the comment that corresponds to this grade (empty string if there is not one.
*/
function quiz_report_feedback_for_grade($grade, $quizid) {
static $feedbackcache = array();
if (!isset($feedbackcache[$quizid])){
$feedbackcache[$quizid] = get_records('quiz_feedback', 'quizid', $quizid);
}
$feedbacks = $feedbackcache[$quizid];
$feedbacktext = '';
foreach ($feedbacks as $feedback) {
if ($feedback->mingrade <= $grade && $grade < $feedback->maxgrade){
$feedbacktext = $feedback->feedbacktext;
break;
}
}
// Clean the text, ready for display.
$formatoptions = new stdClass;
$formatoptions->noclean = true;
$feedbacktext = format_text($feedbacktext, FORMAT_MOODLE, $formatoptions);
return $feedbacktext;
}
?>