report_customlang: regenerate foreign key after recent tables rename
[moodle.git] / mod / quiz / report / responses / responses_table.php
CommitLineData
aeb15530 1<?php
e84cb615 2define ('QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY', 150);
7f29a7db 3
4class quiz_report_responses_table extends table_sql {
5
6 var $useridfield = 'userid';
7
8 var $reporturl;
9 var $displayoptions;
10
11 function quiz_report_responses_table($quiz , $qmsubselect, $groupstudents,
8ad67658 12 $students, $questions, $candelete, $reporturl, $displayoptions, $context){
7f29a7db 13 parent::table_sql('mod-quiz-report-responses-report');
14 $this->quiz = $quiz;
15 $this->qmsubselect = $qmsubselect;
16 $this->groupstudents = $groupstudents;
17 $this->students = $students;
18 $this->questions = $questions;
19 $this->candelete = $candelete;
20 $this->reporturl = $reporturl;
21 $this->displayoptions = $displayoptions;
8ad67658 22 $this->context = $context;
7f29a7db 23 }
24 function build_table(){
7f29a7db 25 if ($this->rawdata) {
3b518020 26 $this->strtimeformat = str_replace(',', ' ', get_string('strftimedatetime'));
7f29a7db 27 parent::build_table();
7f29a7db 28 }
29 }
30
31 function wrap_html_start(){
32 if (!$this->is_downloading()) {
33 if ($this->candelete) {
34 // Start form
6ea66ff3 35 $displayurl = new moodle_url($this->reporturl, $this->displayoptions);
7f29a7db 36 $strreallydel = addslashes_js(get_string('deleteattemptcheck','quiz'));
37 echo '<div id="tablecontainer">';
eb788065 38 echo '<form id="attemptsform" method="post" action="' . $displayurl->out_omit_querystring() .
7f29a7db 39 '" onsubmit="confirm(\''.$strreallydel.'\');">';
40 echo '<div style="display: none;">';
6ea66ff3 41 echo html_writer::input_hidden_params($displayurl);
db77f410 42 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())) . "\n";
7f29a7db 43 echo '</div>';
44 echo '<div>';
45 }
46 }
47 }
48 function wrap_html_finish(){
49 if (!$this->is_downloading()) {
50 // Print "Select all" etc.
51 if ($this->candelete) {
670b8954 52 echo '<div id="commands">';
7f29a7db 53 echo '<a href="javascript:select_all_in(\'DIV\',null,\'tablecontainer\');">'.
54 get_string('selectall', 'quiz').'</a> / ';
55 echo '<a href="javascript:deselect_all_in(\'DIV\',null,\'tablecontainer\');">'.
56 get_string('selectnone', 'quiz').'</a> ';
57 echo '&nbsp;&nbsp;';
6559096f 58 echo '<input type="submit" value="'.get_string('deleteselected', 'quiz_overview').'"/>';
670b8954 59 echo '</div>';
7f29a7db 60 // Close form
61 echo '</div>';
62 echo '</form></div>';
63 }
64 }
65 }
66
67
68 function col_checkbox($attempt){
69 if ($attempt->attempt){
70 return '<input type="checkbox" name="attemptid[]" value="'.$attempt->attempt.'" />';
71 } else {
72 return '';
73 }
74 }
75
76 function col_picture($attempt){
39e37019 77 global $COURSE, $OUTPUT;
39790bd8 78 $user = new stdClass();
35bf6352 79 $user->id = $attempt->userid;
80 $user->lastname = $attempt->lastname;
81 $user->firstname = $attempt->firstname;
82 $user->imagealt = $attempt->imagealt;
83 $user->picture = $attempt->picture;
3a11c09f 84 $user->email = $attempt->email;
812dbaf7 85 return $OUTPUT->user_picture($user);
7f29a7db 86 }
87
88
89 function col_timestart($attempt){
90 if ($attempt->attempt) {
91 $startdate = userdate($attempt->timestart, $this->strtimeformat);
92 if (!$this->is_downloading()) {
93 return '<a href="review.php?q='.$this->quiz->id.'&amp;attempt='.$attempt->attempt.'">'.$startdate.'</a>';
94 } else {
95 return $startdate;
96 }
97 } else {
98 return '-';
99 }
100 }
101 function col_timefinish($attempt){
102 if ($attempt->attempt) {
103 if ($attempt->timefinish) {
104 $timefinish = userdate($attempt->timefinish, $this->strtimeformat);
105 if (!$this->is_downloading()) {
106 return '<a href="review.php?q='.$this->quiz->id.'&amp;attempt='.$attempt->attempt.'">'.$timefinish.'</a>';
107 } else {
108 return $timefinish;
109 }
110 } else {
111 return '-';
112 }
113 } else {
114 return '-';
115 }
116 }
117
118 function col_duration($attempt){
119 if ($attempt->timefinish) {
ea906bb4 120 return format_time($attempt->timefinish - $attempt->timestart);
7f29a7db 121 } elseif ($attempt->timestart) {
122 return get_string('unfinished', 'quiz');
123 } else {
124 return '-';
125 }
126 }
ea906bb4 127
7f29a7db 128 function col_sumgrades($attempt){
129 if ($attempt->timefinish) {
130 $grade = quiz_rescale_grade($attempt->sumgrades, $this->quiz);
131 if (!$this->is_downloading()) {
132 $gradehtml = '<a href="review.php?q='.$this->quiz->id.'&amp;attempt='.$attempt->attempt.'">'.$grade.'</a>';
133 if ($this->qmsubselect && $attempt->gradedattempt){
134 $gradehtml = '<div class="highlight">'.$gradehtml.'</div>';
135 }
136 return $gradehtml;
137 } else {
138 return $grade;
139 }
140 } else {
141 return '-';
142 }
143 }
144 function other_cols($colname, $attempt){
ca4b4f8f 145 global $QTYPES, $OUTPUT;
3e71541f 146 static $states =array();
7f29a7db 147 if (preg_match('/^qsanswer([0-9]+)$/', $colname, $matches)){
3f8e526e 148 if ($attempt->uniqueid == 0) {
149 return '-';
150 }
7f29a7db 151 $questionid = $matches[1];
2ea2c1f5 152 if (isset($this->gradedstatesbyattempt[$attempt->uniqueid][$questionid])){
153 $stateforqinattempt = $this->gradedstatesbyattempt[$attempt->uniqueid][$questionid];
154 } else {
155 return '-';
156 }
aeb15530 157
7f29a7db 158 $question = $this->questions[$questionid];
2ea2c1f5 159 restore_question_state($question, $stateforqinattempt);
aeb15530 160
2280e147 161 if (!$this->is_downloading() || $this->is_downloading() == 'xhtml'){
162 $formathtml = true;
8968f51f 163 } else {
2280e147 164 $formathtml = false;
8968f51f 165 }
ca4b4f8f 166
2280e147 167 $summary = $QTYPES[$question->qtype]->response_summary($question, $stateforqinattempt,
168 QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY, $formathtml);
7f29a7db 169 if (!$this->is_downloading()) {
2280e147 170 if ($summary){
9bf16314
PS
171 $link = new moodle_url("/mod/quiz/reviewquestion.php?attempt=$attempt->attempt&question=$question->id");
172 $action = new popup_action('click', $link, 'reviewquestion', array('height' => 450, 'width' => 650));
173 $summary = $OUTPUT->action_link($link, $summary, $action, array('title'=>$question->formattedname));
ca4b4f8f 174
8968f51f 175 if (question_state_is_graded($stateforqinattempt)
26da840f 176 && ($question->maxgrade > 0)){
8968f51f 177 $grade = $stateforqinattempt->grade
2280e147 178 / $question->maxgrade;
8968f51f 179 $qclass = question_get_feedback_class($grade);
180 $feedbackimg = question_get_feedback_image($grade);
181 $questionclass = "que";
2280e147 182 return "<span class=\"$questionclass\"><span class=\"$qclass\">".$summary."</span></span>$feedbackimg";
e1d2278b 183 } else {
2280e147 184 return $summary;
e1d2278b 185 }
7f29a7db 186 } else {
199b946f 187 return '';
188 }
aeb15530 189
7f29a7db 190 } else {
2280e147 191 return $summary;
7f29a7db 192 }
193 } else {
194 return NULL;
195 }
196 }
197
198 function col_feedbacktext($attempt){
199 if ($attempt->timefinish) {
200 if (!$this->is_downloading()) {
8ad67658 201 return quiz_report_feedback_for_grade(quiz_rescale_grade($attempt->sumgrades, $this->quiz, false), $this->quiz->id, $this->context);
7f29a7db 202 } else {
8ad67658 203 return strip_tags(quiz_report_feedback_for_grade(quiz_rescale_grade($attempt->sumgrades, $this->quiz, false), $this->quiz->id, $this->context));
7f29a7db 204 }
205 } else {
206 return '-';
207 }
208
209 }
210
211 function query_db($pagesize, $useinitialsbar=true){
212 // Add table joins so we can sort by question answer
213 // unfortunately can't join all tables necessary to fetch all answers
214 // to get the state for one question per attempt row we must join two tables
215 // and there is a limit to how many joins you can have in one query. In MySQL it
216 // is 61. This means that when having more than 29 questions the query will fail.
217 // So we join just the tables needed to sort the attempts.
218 if($sort = $this->get_sql_sort()) {
219 $this->sql->from .= ' ';
220 $sortparts = explode(',', $sort);
221 $matches = array();
222 foreach($sortparts as $sortpart) {
223 $sortpart = trim($sortpart);
224 if (preg_match('/^qsanswer([0-9]+)/', $sortpart, $matches)){
225 $qid = intval($matches[1]);
226 $this->sql->fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.answer AS qsanswer$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
227 $this->sql->from .= "LEFT JOIN {question_sessions} qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = :qid$qid ";
228 $this->sql->from .= "LEFT JOIN {question_states} qs$qid ON qs$qid.id = qns$qid.newgraded ";
229 $this->sql->params['qid'.$qid] = $qid;
230 }
231 }
232 }
233 parent::query_db($pagesize, $useinitialsbar);
2ea2c1f5 234 $qsfields = 'qs.id, qs.grade, qs.event, qs.question, qs.answer, qs.attempt';
235 if (!$this->is_downloading()) {
236 $attemptids = array();
237 foreach ($this->rawdata as $attempt){
238 if ($attempt->uniqueid > 0){
239 $attemptids[] = $attempt->uniqueid;
240 }
241 }
242 $this->gradedstatesbyattempt = quiz_get_newgraded_states($attemptids, true, $qsfields);
243 } else {
244 $this->gradedstatesbyattempt = quiz_get_newgraded_states($this->sql, true, $qsfields);
245 }
7f29a7db 246 }
247}
aeb15530 248