ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilTestTopList.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2015 ILIAS open source, Extended GPL, see docs/LICENSE */
3
8{
10 private $object;
12 private $db;
13
17 public function __construct(ilObjTest $a_object)
18 {
19 global $DIC;
20
21 $this->object = $a_object;
22 $this->db = $DIC->database();
23 }
24
30 public function getUserToplistByWorkingtime(int $a_test_ref_id, int $a_user_id) : array
31 {
32 $result = $this->db->query(
33 '
34 SELECT COUNT(tst_pass_result.workingtime) cnt
35 FROM object_reference
36 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
37 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
38 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
39 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
40 AND tst_pass_result.pass = tst_result_cache.pass
41 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
42 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
43 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
44 AND workingtime <
45 (
46 SELECT workingtime
47 FROM object_reference
48 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
49 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
50 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
51 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
52 AND tst_pass_result.pass = tst_result_cache.pass
53 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
54 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
55 )
56 '
57 );
58 $row = $this->db->fetchAssoc($result);
59 $better_participants = $row['cnt'];
60 $own_placement = $better_participants + 1;
61
62 $result = $this->db->query(
63 '
64 SELECT COUNT(tst_pass_result.workingtime) cnt
65 FROM object_reference
66 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
67 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
68 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
69 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
70 AND tst_pass_result.pass = tst_result_cache.pass
71 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
72 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer')
73 );
74 $row = $this->db->fetchAssoc($result);
75 $number_total = $row['cnt'];
76
77 $result = $this->db->query(
78 '
79 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage ,
80 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
81 FROM object_reference
82 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
83 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
84 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
85 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
86 AND tst_pass_result.pass = tst_result_cache.pass
87 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
88
89 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
90 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
91
92 UNION(
93 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
94 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
95 FROM object_reference
96 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
97 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
98 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
99 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
100 AND tst_pass_result.pass = tst_result_cache.pass
101 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
102 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
103 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
104 AND workingtime >=
105 (
106 SELECT tst_pass_result.workingtime
107 FROM object_reference
108 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
109 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
110 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
111 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
112 AND tst_pass_result.pass = tst_result_cache.pass
113 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
114 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
115 )
116 ORDER BY workingtime DESC
117 LIMIT 0,3
118 )
119 UNION(
120 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
121 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
122 FROM object_reference
123 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
124 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
125 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
126 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
127 AND tst_pass_result.pass = tst_result_cache.pass
128 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
129 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
130 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
131 AND workingtime <
132 (
133 SELECT tst_pass_result.workingtime
134 FROM object_reference
135 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
136 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
137 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
138 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
139 AND tst_pass_result.pass = tst_result_cache.pass
140 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
141 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
142 )
143 ORDER BY workingtime DESC
144 LIMIT 0,3
145 )
146 ORDER BY workingtime ASC
147 LIMIT 0, 7
148 '
149 );
150
151 $i = $own_placement - (($better_participants >= 3) ? 3 : $better_participants);
152
153 $data = [];
154
155 if ($i > 1) {
156 $item = ['Rank' => '...'];
157 $data[] = $item;
158 }
159
160 while ($row = $this->db->fetchAssoc($result)) {
161 $item = $this->getResultTableRow($row, $i, $a_user_id);
162 $i++;
163 $data[] = $item;
164 }
165
166 if ($number_total > $i) {
167 $item = ['Rank' => '...'];
168 $data[] = $item;
169 }
170
171 return $data;
172 }
173
179 public function getGeneralToplistByPercentage(int $a_test_ref_id, int $a_user_id) : array
180 {
181 $this->db->setLimit($this->object->getHighscoreTopNum(), 0);
182 $result = $this->db->query(
183 '
184 SELECT tst_result_cache.*, round(points/maxpoints*100,2) as percentage, tst_pass_result.workingtime, usr_data.usr_id, usr_data.firstname, usr_data.lastname
185 FROM object_reference
186 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
187 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
188 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
189 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi AND tst_pass_result.pass = tst_result_cache.pass
190 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
191 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
192 ORDER BY percentage DESC'
193 );
194
195 $i = 0;
196 $data = [];
197
198 while ($row = $this->db->fetchAssoc($result)) {
199 $i++;
200 $item = $this->getResultTableRow($row, $i, $a_user_id);
201
202 $data[] = $item;
203 }
204
205 return $data;
206 }
207
213 public function getGeneralToplistByWorkingtime(int $a_test_ref_id, int $a_user_id) : array
214 {
215 $this->db->setLimit($this->object->getHighscoreTopNum(), 0);
216 $result = $this->db->query(
217 '
218 SELECT tst_result_cache.*, round(points/maxpoints*100,2) as percentage, tst_pass_result.workingtime, usr_data.usr_id, usr_data.firstname, usr_data.lastname
219 FROM object_reference
220 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
221 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
222 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
223 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi AND tst_pass_result.pass = tst_result_cache.pass
224 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
225 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
226 ORDER BY workingtime ASC'
227 );
228
229 $i = 0;
230 $data = [];
231
232 while ($row = $this->db->fetchAssoc($result)) {
233 $i++;
234 $item = $this->getResultTableRow($row, $i, $a_user_id);
235 $data[] = $item;
236 }
237
238 return $data;
239 }
240
246 public function getUserToplistByPercentage(int $a_test_ref_id, int $a_user_id) : array
247 {
248 $result = $this->db->query(
249 '
250 SELECT COUNT(tst_pass_result.workingtime) cnt
251 FROM object_reference
252 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
253 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
254 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
255 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
256 AND tst_pass_result.pass = tst_result_cache.pass
257 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
258 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
259 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
260 AND round(reached_points/max_points*100) >=
261 (
262 SELECT round(reached_points/max_points*100)
263 FROM object_reference
264 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
265 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
266 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
267 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
268 AND tst_pass_result.pass = tst_result_cache.pass
269 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
270 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
271 )
272 '
273 );
274 $row = $this->db->fetchAssoc($result);
275 $better_participants = $row['cnt'];
276 $own_placement = $better_participants + 1;
277
278 $result = $this->db->query(
279 '
280 SELECT COUNT(tst_pass_result.workingtime) cnt
281 FROM object_reference
282 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
283 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
284 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
285 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
286 AND tst_pass_result.pass = tst_result_cache.pass
287 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
288 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer')
289 );
290 $row = $this->db->fetchAssoc($result);
291 $number_total = $row['cnt'];
292
293 $result = $this->db->query(
294 '
295 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage ,
296 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
297 FROM object_reference
298 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
299 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
300 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
301 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
302 AND tst_pass_result.pass = tst_result_cache.pass
303 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
304
305 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
306 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
307
308 UNION(
309 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
310 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
311 FROM object_reference
312 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
313 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
314 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
315 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
316 AND tst_pass_result.pass = tst_result_cache.pass
317 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
318 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
319 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
320 AND round(reached_points/max_points*100) >=
321 (
322 SELECT round(reached_points/max_points*100)
323 FROM object_reference
324 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
325 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
326 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
327 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
328 AND tst_pass_result.pass = tst_result_cache.pass
329 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
330 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
331 )
332 ORDER BY round(reached_points/max_points*100) ASC
333 LIMIT 0,3
334 )
335 UNION(
336 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
337 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
338 FROM object_reference
339 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
340 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
341 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
342 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
343 AND tst_pass_result.pass = tst_result_cache.pass
344 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
345 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
346 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
347 AND round(reached_points/max_points*100) <=
348 (
349 SELECT round(reached_points/max_points*100)
350 FROM object_reference
351 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
352 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
353 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
354 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
355 AND tst_pass_result.pass = tst_result_cache.pass
356 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
357 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
358 )
359 ORDER BY round(reached_points/max_points*100) ASC
360 LIMIT 0,3
361 )
362 ORDER BY round(reached_points/max_points*100) DESC, tstamp ASC
363 LIMIT 0, 7
364 '
365 );
366
367 $i = $own_placement - (($better_participants >= 3) ? 3 : $better_participants);
368
369 $data = [];
370
371 if ($i > 1) {
372 $item = ['Rank' => '...'];
373 $data[] = $item;
374 }
375
376 while ($row = $this->db->fetchAssoc($result)) {
377 $item = $this->getResultTableRow($row, $i, $a_user_id);
378 $i++;
379 $data[] = $item;
380 }
381
382 if ($number_total > $i) {
383 $item = ['Rank' => '...'];
384 $data[] = $item;
385 }
386
387 return $data;
388 }
389
397 private function getResultTableRow(array $row, int $i, int $usrId) : array
398 {
399 $item = [];
400
401 $item['rank'] = $i . '. ';
402
403 if ($this->object->isHighscoreAnon() && (int) $row['usr_id'] !== $usrId) {
404 $item['participant'] = '-, -';
405 } else {
406 $item['participant'] = $row['lastname'] . ', ' . $row['firstname'];
407 }
408
409 if ($this->object->getHighscoreAchievedTS()) {
410 $item['achieved'] = new ilDateTime($row['tstamp'], IL_CAL_UNIX);
411 }
412
413 if ($this->object->getHighscoreScore()) {
414 $item['score'] = $row['reached_points'] . ' / ' . $row['max_points'];
415 }
416
417 if ($this->object->getHighscorePercentage()) {
418 $item['percentage'] = $row['percentage'] . '%';
419 }
420
421 if ($this->object->getHighscoreHints()) {
422 $item['hints'] = $row['hint_count'];
423 }
424
425 if ($this->object->getHighscoreWTime()) {
426 $item['time'] = $this->formatTime((int) $row['workingtime']);
427 }
428
429 $item['is_actor'] = ((int) $row['usr_id'] === $usrId);
430
431 return $item;
432 }
433
438 private function formatTime(int $seconds) : string
439 {
440 $retval = '';
441 $hours = intval(intval($seconds) / 3600);
442 $retval .= str_pad($hours, 2, "0", STR_PAD_LEFT) . ":";
443 $minutes = intval(($seconds / 60) % 60);
444 $retval .= str_pad($minutes, 2, "0", STR_PAD_LEFT) . ":";
445 $seconds = intval($seconds % 60);
446 $retval .= str_pad($seconds, 2, "0", STR_PAD_LEFT);
447
448 return $retval;
449 }
450}
$result
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_UNIX
@classDescription Date and time handling
Class ilTestTopList.
getGeneralToplistByPercentage(int $a_test_ref_id, int $a_user_id)
getGeneralToplistByWorkingtime(int $a_test_ref_id, int $a_user_id)
getUserToplistByWorkingtime(int $a_test_ref_id, int $a_user_id)
getResultTableRow(array $row, int $i, int $usrId)
formatTime(int $seconds)
__construct(ilObjTest $a_object)
getUserToplistByPercentage(int $a_test_ref_id, int $a_user_id)
$i
Definition: metadata.php:24
$data
Definition: storeScorm.php:23
$DIC
Definition: xapitoken.php:46