]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-15092 "Quiz overview report won't display if there are more than 29 questions...
authorjamiesensei <jamiesensei>
Fri, 6 Jun 2008 13:21:50 +0000 (13:21 +0000)
committerjamiesensei <jamiesensei>
Fri, 6 Jun 2008 13:21:50 +0000 (13:21 +0000)
mod/quiz/report/overview/overview_table.php
mod/quiz/report/overview/report.php
mod/quiz/report/reportlib.php

index 76100729608e3921357a9413902c9fdf1ffe4aff..12614dd817386c2867c1e7de2614f8146441e76c 100644 (file)
@@ -166,20 +166,31 @@ class quiz_report_overview_table extends table_sql {
         }
     }
     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}.'&amp;number='.$question->number,
+                        $stateforqinattempt->id.'&amp;number='.$question->number,
                         'reviewquestion', $grade, 450, 650, get_string('reviewresponse', 'quiz'),
                         'none', true);
             } else {
index 8bc1d399186e615b67956aee59268ccd30a518e4..b3dcbe4a19122c13ba136b900e77225fd343c28e 100644 (file)
@@ -177,15 +177,29 @@ class quiz_report extends quiz_default_report {
          }
         $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 .= ' ';
             }
         }
         
index 950146407a61ce31d3b5806d1f6e97c397c77fd1..f6a65c8d9dadcc94b28eeaee58f4c6f098533fe5 100644 (file)
@@ -11,11 +11,11 @@ define('QUIZ_REPORT_ATTEMPTS_ALL_STUDENTS', 3);
  * 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 " .