Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

346 lines (317 sloc) 16.46 kb
<?php
class quiz_report_overview_table extends table_sql {
var $useridfield = 'userid';
var $candelete;
var $reporturl;
var $displayoptions;
var $regradedqs = array();
function quiz_report_overview_table($quiz , $qmsubselect, $groupstudents,
$students, $detailedmarks, $questions, $candelete, $reporturl, $displayoptions, $context){
parent::table_sql('mod-quiz-report-overview-report');
$this->quiz = $quiz;
$this->qmsubselect = $qmsubselect;
$this->groupstudents = $groupstudents;
$this->students = $students;
$this->detailedmarks = $detailedmarks;
$this->questions = $questions;
$this->candelete = $candelete;
$this->reporturl = $reporturl;
$this->displayoptions = $displayoptions;
$this->context = $context;
}
function build_table(){
global $CFG, $DB;
if ($this->rawdata) {
// Define some things we need later to process raw data from db.
$this->strtimeformat = str_replace(',', '', get_string('strftimedatetime'));
parent::build_table();
//end of adding data from attempts data to table / download
//now add averages at bottom of table :
$params = array($this->quiz->id);
$averagesql = "SELECT AVG(qg.grade) AS grade " .
"FROM {quiz_grades} qg " .
"WHERE quiz=?";
$this->add_separator();
if ($this->is_downloading()){
$namekey = 'lastname';
} else {
$namekey = 'fullname';
}
if ($this->groupstudents){
list($g_usql, $g_params) = $DB->get_in_or_equal($this->groupstudents);
$groupaveragesql = $averagesql." AND qg.userid $g_usql";
$groupaverage = $DB->get_record_sql($groupaveragesql, array_merge($params, $g_params));
$groupaveragerow = array($namekey => get_string('groupavg', 'grades'),
'sumgrades' => quiz_format_grade($this->quiz, $groupaverage->grade),
'feedbacktext'=> strip_tags(quiz_report_feedback_for_grade($groupaverage->grade, $this->quiz->id, $this->context)));
if($this->detailedmarks && ($this->qmsubselect || $this->quiz->attempts == 1)) {
$avggradebyq = quiz_get_average_grade_for_questions($this->quiz, $this->groupstudents);
$groupaveragerow += quiz_format_average_grade_for_questions($avggradebyq, $this->questions, $this->quiz, $this->is_downloading());
}
$this->add_data_keyed($groupaveragerow);
}
if ($this->students) {
list($s_usql, $s_params) = $DB->get_in_or_equal($this->students);
$overallaverage = $DB->get_record_sql($averagesql." AND qg.userid $s_usql", array_merge($params, $s_params));
$overallaveragerow = array($namekey => get_string('overallaverage', 'grades'),
'sumgrades' => quiz_format_grade($this->quiz, $overallaverage->grade),
'feedbacktext'=> strip_tags(quiz_report_feedback_for_grade($overallaverage->grade, $this->quiz->id, $this->context)));
if($this->detailedmarks && ($this->qmsubselect || $this->quiz->attempts == 1)) {
$avggradebyq = quiz_get_average_grade_for_questions($this->quiz, $this->students);
$overallaveragerow += quiz_format_average_grade_for_questions($avggradebyq, $this->questions, $this->quiz, $this->is_downloading());
}
$this->add_data_keyed($overallaveragerow);
}
}
}
function wrap_html_start(){
if (!$this->is_downloading()) {
if ($this->candelete) {
// Start form
$url = new moodle_url($this->reporturl, $this->displayoptions);
echo '<div id="tablecontainer" class="overview-tablecontainer">';
echo '<form id="attemptsform" method="post" action="' . $this->reporturl->out_omit_querystring() .'">';
echo '<div style="display: none;">';
echo html_writer::input_hidden_params($url);
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())) . "\n";
echo '</div>';
echo '<div>';
}
}
}
function wrap_html_finish(){
if (!$this->is_downloading()) {
// Print "Select all" etc.
if ($this->candelete) {
$strreallydel = addslashes_js(get_string('deleteattemptcheck','quiz'));
echo '<div id="commands">';
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;';
if (has_capability('mod/quiz:regrade', $this->context)){
echo '<input type="submit" name="regrade" value="'.get_string('regradeselected', 'quiz_overview').'"/>';
}
echo '<input type="submit" onclick="return confirm(\''.$strreallydel.'\');" name="delete" value="'.get_string('deleteselected', 'quiz_overview').'"/>';
echo '</div>';
// Close form
echo '</div>';
echo '</form></div>';
}
}
}
function col_checkbox($attempt){
if ($attempt->attempt){
return '<input type="checkbox" name="attemptid[]" value="'.$attempt->attempt.'" />';
} else {
return '';
}
}
function col_picture($attempt){
global $COURSE, $OUTPUT;
$user = new stdClass();
$user->id = $attempt->userid;
$user->lastname = $attempt->lastname;
$user->firstname = $attempt->firstname;
$user->imagealt = $attempt->imagealt;
$user->picture = $attempt->picture;
$user->email = $attempt->email;
return $OUTPUT->user_picture($user);
}
function col_fullname($attempt){
$html = parent::col_fullname($attempt);
if ($this->is_downloading()) {
return $html;
}
return $html . '<br /><a class="reviewlink" href="review.php?q='.$this->quiz->id.'&amp;attempt='.$attempt->attempt.
'">'.get_string('reviewattempt', 'quiz').'</a>';
}
function col_timestart($attempt){
if ($attempt->attempt) {
return userdate($attempt->timestart, $this->strtimeformat);
} else {
return '-';
}
}
function col_timefinish($attempt){
if ($attempt->attempt && $attempt->timefinish) {
return userdate($attempt->timefinish, $this->strtimeformat);
} else {
return '-';
}
}
function col_duration($attempt){
if ($attempt->timefinish) {
return format_time($attempt->timefinish - $attempt->timestart);
} elseif ($attempt->timestart) {
return get_string('unfinished', 'quiz');
} else {
return '-';
}
}
function col_sumgrades($attempt){
if (!$attempt->timefinish) {
return '-';
}
$grade = quiz_rescale_grade($attempt->sumgrades, $this->quiz);
if ($this->is_downloading()) {
return $grade;
}
if (isset($this->regradedqs[$attempt->attemptuniqueid])){
$newsumgrade = 0;
$oldsumgrade = 0;
foreach ($this->questions as $question){
if (isset($this->regradedqs[$attempt->attemptuniqueid][$question->id])){
$newsumgrade += $this->regradedqs[$attempt->attemptuniqueid][$question->id]->newgrade;
$oldsumgrade += $this->regradedqs[$attempt->attemptuniqueid][$question->id]->oldgrade;
} else {
$newsumgrade += $this->gradedstatesbyattempt[$attempt->attemptuniqueid][$question->id]->grade;
$oldsumgrade += $this->gradedstatesbyattempt[$attempt->attemptuniqueid][$question->id]->grade;
}
}
$newsumgrade = quiz_rescale_grade($newsumgrade, $this->quiz);
$oldsumgrade = quiz_rescale_grade($oldsumgrade, $this->quiz);
$grade = "<del>$oldsumgrade</del><br />$newsumgrade";
}
$gradehtml = '<a href="review.php?q='.$this->quiz->id.'&amp;attempt='.$attempt->attempt.
'" title="'.get_string('reviewattempt', 'quiz').'">'.$grade.'</a>';
if ($this->qmsubselect && $attempt->gradedattempt){
$gradehtml = '<div class="highlight">'.$gradehtml.'</div>';
}
return $gradehtml;
}
/**
* @param string $colname the name of the column.
* @param object $attempt the row of data - see the SQL in display() in
* mod/quiz/report/overview/report.php to see what fields are present,
* and what they are called.
* @return string the contents of the cell.
*/
function other_cols($colname, $attempt){
global $OUTPUT;
if (preg_match('/^qsgrade([0-9]+)$/', $colname, $matches)){
$questionid = $matches[1];
$question = $this->questions[$questionid];
if (isset($this->gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid])){
$stateforqinattempt = $this->gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid];
} else {
$stateforqinattempt = false;
}
if ($stateforqinattempt && question_state_is_graded($stateforqinattempt)) {
$grade = quiz_rescale_grade($stateforqinattempt->grade, $this->quiz, 'question');
if (!$this->is_downloading()) {
if (isset($this->regradedqs[$attempt->attemptuniqueid][$questionid])){
$gradefromdb = $grade;
$newgrade = quiz_rescale_grade($this->regradedqs[$attempt->attemptuniqueid][$questionid]->newgrade, $this->quiz, 'question');
$oldgrade = quiz_rescale_grade($this->regradedqs[$attempt->attemptuniqueid][$questionid]->oldgrade, $this->quiz, 'question');
$grade = '<del>'.$oldgrade.'</del><br />'.
$newgrade;
}
$link = new moodle_url("/mod/quiz/reviewquestion.php?attempt=$attempt->attempt&question=$question->id");
$action = new popup_action('click', $link, 'reviewquestion', array('height' => 450, 'width' => 650));
$linktopopup = $OUTPUT->action_link($link, $grade, $action, array('title'=>get_string('reviewresponsetoq', 'quiz', $question->formattedname)));
if (($this->questions[$questionid]->maxgrade != 0)){
$fractionofgrade = $stateforqinattempt->grade
/ $this->questions[$questionid]->maxgrade;
$qclass = question_get_feedback_class($fractionofgrade);
$feedbackimg = question_get_feedback_image($fractionofgrade);
$questionclass = "que";
return "<span class=\"$questionclass\"><span class=\"$qclass\">".$linktopopup."</span></span>$feedbackimg";
} else {
return $linktopopup;
}
} else {
return $grade;
}
} else if ($stateforqinattempt && question_state_is_closed($stateforqinattempt)) {
$text = get_string('requiresgrading', 'quiz_overview');
if (!$this->is_downloading()) {
$link = new moodle_url("/mod/quiz/reviewquestion.php?attempt=$attempt->attempt&question=$question->id");
$action = new popup_action('click', $link, 'reviewquestion', array('height' => 450, 'width' => 650));
return $OUTPUT->action_link($link, $text, $action, array('title'=>get_string('reviewresponsetoq', 'quiz', $question->formattedname)));
} else {
return $text;
}
} else {
return '--';
}
} else {
return NULL;
}
}
function col_feedbacktext($attempt){
if ($attempt->timefinish) {
if (!$this->is_downloading()) {
return quiz_report_feedback_for_grade(quiz_rescale_grade($attempt->sumgrades, $this->quiz, false), $this->quiz->id, $this->context);
} else {
return strip_tags(quiz_report_feedback_for_grade(quiz_rescale_grade($attempt->sumgrades, $this->quiz, false), $this->quiz->id, $this->context));
}
} else {
return '-';
}
}
function col_regraded($attempt){
if ($attempt->regraded == '') {
return '';
} else if ($attempt->regraded == 0) {
return get_string('needed', 'quiz_overview');
} else if ($attempt->regraded == 1) {
return get_string('done', 'quiz_overview');
}
}
function query_db($pagesize, $useinitialsbar=true){
// 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 = $this->get_sql_sort()) {
if ($this->detailedmarks) {
$this->sql->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]);
$this->sql->fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
$this->sql->from .= "LEFT JOIN {question_sessions} qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = :qid$qid ";
$this->sql->from .= "LEFT JOIN {question_states} qs$qid ON qs$qid.id = qns$qid.newgraded ";
$this->sql->params['qid'.$qid] = $qid;
}
}
} else {
//unset any sort columns that sort on question grade as the
//grades are not being fetched as fields
$sess = &$this->sess;
foreach($sess->sortby as $column => $order) {
if (preg_match('/^qsgrade([0-9]+)/', trim($column))){
unset($sess->sortby[$column]);
}
}
}
}
parent::query_db($pagesize, $useinitialsbar);
//get all the attempt ids we want to display on this page
//or to export for download.
if (!$this->is_downloading()) {
$attemptids = array();
foreach ($this->rawdata as $attempt){
if ($attempt->attemptuniqueid > 0){
$attemptids[] = $attempt->attemptuniqueid;
}
}
$this->gradedstatesbyattempt = quiz_get_newgraded_states($attemptids, true, 'qs.id, qs.grade, qs.event, qs.question, qs.attempt');
if (has_capability('mod/quiz:regrade', $this->context)){
$this->regradedqs = quiz_get_regraded_qs($attemptids);
}
} else {
$this->gradedstatesbyattempt = quiz_get_newgraded_states($this->sql, true, 'qs.id, qs.grade, qs.event, qs.question, qs.attempt');
if (has_capability('mod/quiz:regrade', $this->context)){
$this->regradedqs = quiz_get_regraded_qs($this->sql);
}
}
}
}
Jump to Line
Something went wrong with that request. Please try again.