}
}
function other_cols($colname, $attempt){
+ static $gradedstatesbyattempt = null;
+ if ($gradedstatesbyattempt === null){
+ //get all the attempt ids we want to display on this page
+ //or to export for download.
+ $attemptids = array();
+ foreach ($this->rawdata as $attempt){
+ if ($attempt->attemptuniqueid > 0){
+ $attemptids[] = $attempt->attemptuniqueid;
+ }
+ }
+ $gradedstatesbyattempt = quiz_get_newgraded_states($attemptids, true, 'qs.id, qs.grade, qs.event, qs.question, qs.attempt');
+ }
if (preg_match('/^qsgrade([0-9]+)$/', $colname, $matches)){
$questionid = $matches[1];
$question = $this->questions[$questionid];
- $state = new object();
- $state->event = $attempt->{'qsevent'.$questionid};
- if (question_state_is_graded($state)) {
- $grade = quiz_rescale_grade($attempt->{'qsgrade'.$questionid}, $this->quiz);
+ $stateforqinattempt = $gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid];
+ if (question_state_is_graded($stateforqinattempt)) {
+ $grade = quiz_rescale_grade($stateforqinattempt->grade, $this->quiz);
} else {
$grade = '--';
}
if (!$this->is_downloading()) {
$grade = $grade.'/'.quiz_rescale_grade($question->grade, $this->quiz);
return link_to_popup_window('/mod/quiz/reviewquestion.php?state='.
- $attempt->{'qsid'.$questionid}.'&number='.$question->number,
+ $stateforqinattempt->id.'&number='.$question->number,
'reviewquestion', $grade, 450, 650, get_string('reviewresponse', 'quiz'),
'none', true);
} else {
}
$table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where");
- if ($detailedmarks) {
- // we want to display marks for all questions
- // Add extra sql to get question grades
- $from .= ' ';
- // we want to display marks for all questions
- foreach (array_keys($questions) as $qid) {
- $fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
- $from .= "LEFT JOIN {$CFG->prefix}question_sessions qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = $qid ";
- $from .= "LEFT JOIN {$CFG->prefix}question_states qs$qid ON qs$qid.id = qns$qid.newgraded ";
+ // 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 = $table->get_sql_sort()) {
+ if (!$table->is_downloading() && $detailedmarks) {
+ $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]);
+ $fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
+ $from .= "LEFT JOIN {$CFG->prefix}question_sessions qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = $qid ";
+ $from .= "LEFT JOIN {$CFG->prefix}question_states qs$qid ON qs$qid.id = qns$qid.newgraded ";
+ } else {
+ $newsort[] = $sortpart;
+ }
+ }
+ $select .= ' ';
}
}
* uniqueid field from quiz_attempt table not the id. Use question_state_is_graded
* function to check that the question is actually graded.
*/
-function quiz_get_newgraded_states($attemptids, $idxattemptq = true){
+function quiz_get_newgraded_states($attemptids, $idxattemptq = true, $fields='qs.*'){
global $CFG;
if ($attemptids){
$attemptidlist = join($attemptids, ',');
- $gradedstatesql = "SELECT qs.* FROM " .
+ $gradedstatesql = "SELECT $fields FROM " .
"{$CFG->prefix}question_sessions qns, " .
"{$CFG->prefix}question_states qs " .
"WHERE qns.attemptid IN ($attemptidlist) AND " .