98ad7484 |
1 | <?php //$Id$ |
2 | |
3 | define('GRADE_FORMAT_PCT', 1); |
4 | define('GRADE_FORMAT_FRA', 2); |
5 | define('GRADE_FORMAT_ABS', 3); |
6 | |
7 | class block_quiz_results extends block_base { |
8 | function init() { |
9 | $this->title = get_string('formaltitle', 'block_quiz_results'); |
10 | $this->content_type = BLOCK_TYPE_TEXT; |
6b4dc5a3 |
11 | $this->version = 2005012600; |
98ad7484 |
12 | } |
13 | |
14 | function get_content() { |
15 | global $USER, $CFG; |
16 | |
17 | if ($this->content !== NULL) { |
18 | return $this->content; |
19 | } |
20 | if (empty($this->instance)) { |
21 | $this->content = ''; |
22 | return $this->content; |
23 | } |
24 | |
25 | $this->content = new stdClass; |
26 | $this->content->text = ''; |
27 | $this->content->footer = ''; |
28 | |
29 | if($this->instance->pagetype == MOODLE_PAGE_COURSE) { |
30 | // We need to see if we are monitoring a quiz |
31 | $quizid = empty($this->config->quizid) ? 0 : $this->config->quizid; |
32 | $courseid = $this->instance->pageid; |
33 | } |
34 | else { |
35 | // Assuming we are displayed in the quiz view page |
36 | // TODO |
37 | $quizid = 0; |
38 | $courseid = 0; |
39 | } |
40 | |
41 | if(empty($quizid)) { |
6b4dc5a3 |
42 | $this->content->text = get_string('error_emptyquizid', 'block_quiz_results'); |
98ad7484 |
43 | return $this->content; |
44 | } |
45 | |
46 | // Get the quiz record |
47 | $quiz = get_record('quiz', 'id', $quizid); |
48 | if(empty($quiz)) { |
6b4dc5a3 |
49 | $this->content->text = get_string('error_emptyquizrecord', 'block_quiz_results'); |
98ad7484 |
50 | return $this->content; |
51 | } |
52 | |
53 | // Get the grades for this quiz |
3779fd55 |
54 | $grades = get_records('quiz_grades', 'quiz', $quizid, 'grade, timemodified DESC'); |
98ad7484 |
55 | |
56 | if(empty($grades)) { |
57 | // No grades, sorry |
6b4dc5a3 |
58 | // The block will hide itself in this case |
00a4237f |
59 | return $this->content; |
98ad7484 |
60 | } |
61 | |
6b4dc5a3 |
62 | $groupmode = NOGROUPS; |
63 | $best = array(); |
64 | $worst = array(); |
98ad7484 |
65 | |
66 | if(!empty($this->config->usegroups)) { |
6b4dc5a3 |
67 | // The block was configured to operate in group mode |
68 | $course = get_record_select('course', 'id = '.$courseid, 'groupmode, groupmodeforce'); |
69 | if($course->groupmodeforce) { |
70 | $groupmode = $course->groupmode; |
71 | } |
72 | else { |
73 | $module = get_record_sql('SELECT cm.groupmode FROM '.$CFG->prefix.'modules m LEFT JOIN '.$CFG->prefix.'course_modules cm ON m.id = cm.module WHERE m.name = \'quiz\' AND cm.instance = '.$quizid); |
74 | $groupmode = $module->groupmode; |
75 | } |
76 | // The actual groupmode for the quiz is now known to be $groupmode |
98ad7484 |
77 | } |
6b4dc5a3 |
78 | |
79 | if($groupmode != NOGROUPS) { |
80 | // Group mode |
81 | |
82 | // Pull out the course groups |
83 | $groups = get_groups($courseid); |
84 | |
85 | if(empty($groups)) { |
86 | // No groups exist, sorry |
87 | $this->content->text = get_string('error_nogroupsexist', 'block_quiz_results'); |
88 | return $this->content; |
89 | } |
90 | |
91 | // Find out all the userids which have a submitted grade |
92 | $userids = array(); |
93 | foreach($grades as $grade) { |
94 | $userids[] = $grade->userid; |
95 | } |
96 | |
97 | // Now find which groups these users belong in |
98 | $groupofuser = get_records_sql( |
99 | 'SELECT m.userid, m.groupid, g.name FROM '.$CFG->prefix.'groups g LEFT JOIN '.$CFG->prefix.'groups_members m ON g.id = m.groupid '. |
100 | 'WHERE g.courseid = '.$courseid.' AND m.userid IN ('.implode(',', $userids).')' |
101 | ); |
102 | |
103 | $groupgrades = array(); |
104 | |
105 | // OK... now, iterate the grades again and sum them up for each group |
106 | foreach($grades as $grade) { |
107 | if(isset($groupofuser[$grade->userid])) { |
108 | // Count this result only if the user is in a group |
109 | $groupid = $groupofuser[$grade->userid]->groupid; |
110 | if(!isset($groupgrades[$groupid])) { |
3779fd55 |
111 | $groupgrades[$groupid] = array('sum' => floatval($grade->grade), 'number' => 1, 'group' => $groupofuser[$grade->userid]->name); |
6b4dc5a3 |
112 | } |
113 | else { |
114 | $groupgrades[$groupid]['sum'] += $grade->grade; |
115 | ++$groupgrades[$groupid]['number']; |
116 | } |
117 | } |
118 | } |
119 | |
3779fd55 |
120 | foreach($groupgrades as $groupid => $groupgrade) { |
121 | $groupgrades[$groupid]['average'] = $groupgrades[$groupid]['sum'] / $groupgrades[$groupid]['number']; |
122 | } |
123 | |
124 | // Sort groupgrades according to average grade, ascending |
125 | uasort($groupgrades, create_function('$a, $b', 'if($a["average"] == $b["average"]) return 0; return ($a["average"] > $b["average"] ? 1 : -1);')); |
6b4dc5a3 |
126 | |
127 | // How many groups do we have with graded member submissions to show? |
128 | $numbest = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($groupgrades)); |
129 | $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($groupgrades) - $numbest); |
130 | |
131 | // Collect all the group results we are going to use in $best and $worst |
132 | $remaining = $numbest; |
133 | $groupgrade = end($groupgrades); |
134 | while($remaining--) { |
3779fd55 |
135 | $best[key($groupgrades)] = $groupgrade['average']; |
6b4dc5a3 |
136 | $groupgrade = prev($groupgrades); |
137 | } |
138 | |
139 | $remaining = $numworst; |
140 | $groupgrade = reset($groupgrades); |
141 | while($remaining--) { |
3779fd55 |
142 | $worst[key($groupgrades)] = $groupgrade['average']; |
6b4dc5a3 |
143 | $groupgrade = next($groupgrades); |
144 | } |
145 | |
146 | // Ready for output! |
147 | $gradeformat = intval(empty($this->config->gradeformat) ? GRADE_FORMAT_PCT : $this->config->gradeformat); |
148 | |
149 | $this->content->text .= '<h1><a href="'.$CFG->wwwroot.'/mod/quiz/view.php?q='.$quizid.'">'.$quiz->name.'</a></h1>'; |
150 | |
151 | $rank = 0; |
152 | if(!empty($best)) { |
9c581405 |
153 | $this->content->text .= '<table class="grades"><caption>'.get_string('bestgroupgrades', 'block_quiz_results', $numbest).'</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>'; |
6b4dc5a3 |
154 | foreach($best as $groupid => $averagegrade) { |
9c581405 |
155 | $this->content->text .= '<tr><td>'.(++$rank).'.</td><td><a href="'.$CFG->wwwroot.'/course/group.php?group='.$groupid.'&id='.$courseid.'">'.$groupgrades[$groupid]['group'].'</a></td><td>'; |
6b4dc5a3 |
156 | switch($gradeformat) { |
157 | case GRADE_FORMAT_FRA: |
158 | $this->content->text .= ($averagegrade.'/'.$quiz->grade); |
159 | break; |
160 | case GRADE_FORMAT_ABS: |
161 | $this->content->text .= $averagegrade; |
162 | break; |
163 | default: |
164 | case GRADE_FORMAT_PCT: |
165 | $this->content->text .= round(floatval($averagegrade) / floatval($quiz->grade) * 100).'%'; |
166 | break; |
167 | } |
168 | $this->content->text .= '</td></tr>'; |
169 | } |
170 | $this->content->text .= '</tbody></table>'; |
171 | } |
172 | |
173 | $rank = 0; |
174 | if(!empty($worst)) { |
175 | $worst = array_reverse($worst, true); |
9c581405 |
176 | $this->content->text .= '<table class="grades"><caption>'.get_string('worstgroupgrades', 'block_quiz_results', $numworst).'</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>'; |
6b4dc5a3 |
177 | foreach($worst as $groupid => $averagegrade) { |
9c581405 |
178 | $this->content->text .= '<tr><td>'.(++$rank).'.</td><td><a href="'.$CFG->wwwroot.'/course/group.php?group='.$groupid.'&id='.$courseid.'">'.$groupgrades[$groupid]['group'].'</a></td><td>'; |
6b4dc5a3 |
179 | switch($gradeformat) { |
180 | case GRADE_FORMAT_FRA: |
181 | $this->content->text .= ($averagegrade.'/'.$quiz->grade); |
182 | break; |
183 | case GRADE_FORMAT_ABS: |
184 | $this->content->text .= $averagegrade; |
185 | break; |
186 | default: |
187 | case GRADE_FORMAT_PCT: |
188 | $this->content->text .= round(floatval($averagegrade) / floatval($quiz->grade) * 100).'%'; |
189 | break; |
190 | } |
191 | $this->content->text .= '</td></tr>'; |
192 | } |
193 | $this->content->text .= '</tbody></table>'; |
194 | } |
195 | } |
196 | |
197 | |
98ad7484 |
198 | else { |
199 | // Single user mode |
6b4dc5a3 |
200 | $numbest = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($grades)); |
201 | $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($grades) - $numbest); |
98ad7484 |
202 | |
203 | // Collect all the usernames we are going to need |
204 | $remaining = $numbest; |
205 | $grade = end($grades); |
206 | while($remaining--) { |
207 | $best[$grade->userid] = $grade->id; |
208 | $grade = prev($grades); |
209 | } |
210 | |
211 | $remaining = $numworst; |
212 | $grade = reset($grades); |
213 | while($remaining--) { |
214 | $worst[$grade->userid] = $grade->id; |
215 | $grade = next($grades); |
216 | } |
217 | |
218 | if(empty($best) && empty($worst)) { |
219 | // Nothing to show, for some reason... |
220 | return $this->content; |
221 | } |
222 | |
223 | // Now grab all the users from the database |
224 | $userids = array_merge(array_keys($best), array_keys($worst)); |
225 | $users = get_records_list('user', 'id', implode(',',$userids), '', 'id, firstname, lastname'); |
226 | |
227 | // Ready for output! |
228 | |
229 | $gradeformat = intval(empty($this->config->gradeformat) ? GRADE_FORMAT_PCT : $this->config->gradeformat); |
230 | |
231 | $this->content->text .= '<h1><a href="'.$CFG->wwwroot.'/mod/quiz/view.php?q='.$quizid.'">'.$quiz->name.'</a></h1>'; |
232 | |
233 | $rank = 0; |
234 | if(!empty($best)) { |
9c581405 |
235 | $this->content->text .= '<table class="grades"><caption>'.get_string('bestgrades', 'block_quiz_results', $numbest).'</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>'; |
98ad7484 |
236 | foreach($best as $userid => $gradeid) { |
9c581405 |
237 | $this->content->text .= '<tr><td>'.(++$rank).'.</td><td><a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'&course='.$courseid.'">'.fullname($users[$userid]).'</a></td><td>'; |
98ad7484 |
238 | switch($gradeformat) { |
239 | case GRADE_FORMAT_FRA: |
240 | $this->content->text .= ($grades[$gradeid]->grade.'/'.$quiz->grade); |
241 | break; |
242 | case GRADE_FORMAT_ABS: |
243 | $this->content->text .= $grades[$gradeid]->grade; |
244 | break; |
245 | default: |
246 | case GRADE_FORMAT_PCT: |
6b4dc5a3 |
247 | $this->content->text .= round(floatval($grades[$gradeid]->grade) / floatval($quiz->grade) * 100).'%'; |
98ad7484 |
248 | break; |
249 | } |
250 | $this->content->text .= '</td></tr>'; |
251 | } |
252 | $this->content->text .= '</tbody></table>'; |
253 | } |
254 | |
255 | $rank = 0; |
256 | if(!empty($worst)) { |
257 | $worst = array_reverse($worst, true); |
9c581405 |
258 | $this->content->text .= '<table class="grades"><caption>'.get_string('worstgrades', 'block_quiz_results', $numworst).'</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>'; |
98ad7484 |
259 | foreach($worst as $userid => $gradeid) { |
9c581405 |
260 | $this->content->text .= '<tr><td>'.(++$rank).'.</td><td><a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'&course='.$courseid.'">'.fullname($users[$userid]).'</a></td><td>'; |
98ad7484 |
261 | switch($gradeformat) { |
262 | case GRADE_FORMAT_FRA: |
263 | $this->content->text .= ($grades[$gradeid]->grade.'/'.$quiz->grade); |
264 | break; |
265 | case GRADE_FORMAT_ABS: |
266 | $this->content->text .= $grades[$gradeid]->grade; |
267 | break; |
268 | default: |
269 | case GRADE_FORMAT_PCT: |
6b4dc5a3 |
270 | $this->content->text .= round(floatval($grades[$gradeid]->grade) / floatval($quiz->grade) * 100).'%'; |
98ad7484 |
271 | break; |
272 | } |
273 | $this->content->text .= '</td></tr>'; |
274 | } |
275 | $this->content->text .= '</tbody></table>'; |
276 | } |
277 | |
278 | } |
279 | |
280 | |
281 | return $this->content; |
282 | } |
283 | |
284 | function instance_allow_config() { |
285 | return true; |
286 | } |
287 | } |
288 | |
289 | ?> |