ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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 }
getUserToplistByWorkingtime(int $a_test_ref_id, int $a_user_id)
getGeneralToplistByPercentage(int $a_test_ref_id, int $a_user_id)
$data
Definition: storeScorm.php:23
Class ilTestTopList.
$result
__construct(ilObjTest $a_object)
const IL_CAL_UNIX
formatTime(int $seconds)
getUserToplistByPercentage(int $a_test_ref_id, int $a_user_id)
global $DIC
Definition: goto.php:24
getGeneralToplistByWorkingtime(int $a_test_ref_id, int $a_user_id)
getResultTableRow(array $row, int $i, int $usrId)
$i
Definition: metadata.php:24