ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
TestTopListRepository.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
24 {
25  public function __construct(
26  private readonly \ilDBInterface $db
27  ) {
28  }
29 
30  public function getGeneralToplist(\ilObjTest $object, TopListOrder $order_by): \Generator
31  {
32  $order_stmt = $order_by === TopListOrder::BY_TIME ? 'tst_pass_result.workingtime' : 'percentage';
33  $this->db->setLimit($object->getHighscoreTopNum(), 0);
34  $result = $this->db->query(
35  '
36  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
37  FROM object_reference
38  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
39  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
40  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
41  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi AND tst_pass_result.pass = tst_result_cache.pass
42  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
43  WHERE object_reference.ref_id = ' . $this->db->quote($object->getRefId(), 'integer') .
44  ' ORDER BY ' . $order_stmt . ' DESC'
45  );
46 
47  while ($row = $this->db->fetchAssoc($result)) {
48  yield $row;
49  }
50  }
51 
52  public function getUserToplistByPercentage(\ilObjTest $object, int $a_user_id): \Generator
53  {
54  $a_test_ref_id = $object->getRefId();
55  $result = $this->db->query(
56  '
57  SELECT COUNT(tst_pass_result.workingtime) cnt
58  FROM object_reference
59  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
60  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
61  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
62  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
63  AND tst_pass_result.pass = tst_result_cache.pass
64  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
65  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
66  AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
67  AND round(reached_points/max_points*100) >=
68  (
69  SELECT round(reached_points/max_points*100)
70  FROM object_reference
71  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
72  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
73  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
74  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
75  AND tst_pass_result.pass = tst_result_cache.pass
76  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
77  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
78  )
79  '
80  );
81  $row = $this->db->fetchAssoc($result);
82  $better_participants = $row['cnt'];
83  $own_placement = $better_participants + 1;
84 
85  $result = $this->db->query(
86  '
87  SELECT COUNT(tst_pass_result.workingtime) cnt
88  FROM object_reference
89  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
90  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
91  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
92  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
93  AND tst_pass_result.pass = tst_result_cache.pass
94  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
95  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer')
96  );
97  $row = $this->db->fetchAssoc($result);
98  $number_total = $row['cnt'];
99 
100  $result = $this->db->query(
101  '
102  SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage ,
103  tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
104  FROM object_reference
105  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
106  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
107  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
108  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
109  AND tst_pass_result.pass = tst_result_cache.pass
110  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
111 
112  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
113  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
114 
115  UNION(
116  SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
117  tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
118  FROM object_reference
119  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
120  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
121  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
122  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
123  AND tst_pass_result.pass = tst_result_cache.pass
124  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
125  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
126  AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
127  AND round(reached_points/max_points*100) >=
128  (
129  SELECT round(reached_points/max_points*100)
130  FROM object_reference
131  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
132  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
133  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
134  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
135  AND tst_pass_result.pass = tst_result_cache.pass
136  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
137  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
138  )
139  ORDER BY round(reached_points/max_points*100) ASC
140  LIMIT 0, ' . $this->db->quote($object->getHighscoreTopNum(), 'integer') . '
141  )
142  UNION(
143  SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
144  tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
145  FROM object_reference
146  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
147  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
148  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
149  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
150  AND tst_pass_result.pass = tst_result_cache.pass
151  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
152  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
153  AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
154  AND round(reached_points/max_points*100) <=
155  (
156  SELECT round(reached_points/max_points*100)
157  FROM object_reference
158  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
159  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
160  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
161  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
162  AND tst_pass_result.pass = tst_result_cache.pass
163  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
164  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
165  )
166  ORDER BY round(reached_points/max_points*100) ASC
167  LIMIT 0, ' . $this->db->quote($object->getHighscoreTopNum(), 'integer') . '
168  )
169  ORDER BY round(reached_points/max_points*100) DESC, tstamp ASC
170  LIMIT 0, ' . $this->db->quote($object->getHighscoreTopNum(), 'integer') . '
171  '
172  );
173 
174  $i = $own_placement - ($better_participants >= $object->getHighscoreTopNum()
175  ? $object->getHighscoreTopNum() : $better_participants);
176 
177  if ($i > 1) {
178  yield $this->buildEmptyItem();
179  }
180 
181  while ($row = $this->db->fetchAssoc($result)) {
182  $i++;
183  yield $row;
184  }
185 
186  if ($number_total > $i) {
187  yield $this->buildEmptyItem();
188  }
189  }
190 
191  public function getUserToplistByWorkingtime(\ilObjTest $object, int $a_user_id): \Generator
192  {
193  $a_test_ref_id = $object->getRefId();
194  $result = $this->db->query(
195  '
196  SELECT COUNT(tst_pass_result.workingtime) cnt
197  FROM object_reference
198  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
199  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
200  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
201  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
202  AND tst_pass_result.pass = tst_result_cache.pass
203  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
204  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
205  AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
206  AND workingtime <
207  (
208  SELECT workingtime
209  FROM object_reference
210  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
211  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
212  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
213  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
214  AND tst_pass_result.pass = tst_result_cache.pass
215  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
216  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
217  )
218  '
219  );
220  $row = $this->db->fetchAssoc($result);
221  $better_participants = $row['cnt'];
222  $own_placement = $better_participants + 1;
223 
224  $result = $this->db->query(
225  '
226  SELECT COUNT(tst_pass_result.workingtime) cnt
227  FROM object_reference
228  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
229  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
230  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
231  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
232  AND tst_pass_result.pass = tst_result_cache.pass
233  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
234  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer')
235  );
236  $row = $this->db->fetchAssoc($result);
237  $number_total = $row['cnt'];
238 
239  $result = $this->db->query(
240  '
241  SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage ,
242  tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
243  FROM object_reference
244  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
245  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
246  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
247  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
248  AND tst_pass_result.pass = tst_result_cache.pass
249  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
250 
251  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
252  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
253 
254  UNION(
255  SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
256  tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
257  FROM object_reference
258  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
259  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
260  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
261  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
262  AND tst_pass_result.pass = tst_result_cache.pass
263  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
264  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
265  AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
266  AND workingtime >=
267  (
268  SELECT tst_pass_result.workingtime
269  FROM object_reference
270  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
271  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
272  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
273  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
274  AND tst_pass_result.pass = tst_result_cache.pass
275  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
276  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
277  )
278  ORDER BY workingtime DESC
279  LIMIT 0, ' . $this->db->quote($object->getHighscoreTopNum(), 'integer') . '
280  )
281  UNION(
282  SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
283  tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
284  FROM object_reference
285  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
286  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
287  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
288  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
289  AND tst_pass_result.pass = tst_result_cache.pass
290  INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
291  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
292  AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
293  AND workingtime <
294  (
295  SELECT tst_pass_result.workingtime
296  FROM object_reference
297  INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
298  INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
299  INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
300  INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
301  AND tst_pass_result.pass = tst_result_cache.pass
302  WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
303  AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
304  )
305  ORDER BY workingtime DESC
306  LIMIT 0, ' . $this->db->quote($object->getHighscoreTopNum(), 'integer') . '
307  )
308  ORDER BY workingtime ASC
309  LIMIT 0, ' . $this->db->quote($object->getHighscoreTopNum(), 'integer') . '
310  '
311  );
312 
313  $i = $own_placement - (($better_participants >= 3) ? 3 : $better_participants);
314 
315  if ($i > 1) {
316  yield $this->buildEmptyItem();
317  }
318 
319  while ($row = $this->db->fetchAssoc($result)) {
320  $i++;
321  yield $row;
322  }
323 
324  if ($number_total > $i) {
325  yield $this->buildEmptyItem();
326  }
327  }
328 
329  private function buildEmptyItem(): array
330  {
331  return [
332  'rank' => '...',
333  'is_actor' => false,
334  'participant' => '',
335  'achieved' => '',
336  'score' => '',
337  'percentage' => '',
338  'time' => ''
339  ];
340  }
341 }
getHighscoreTopNum(int $a_retval=10)
Gets the number of entries which are to be shown in the top-rankings table.
__construct(private readonly \ilDBInterface $db)
getGeneralToplist(\ilObjTest $object, TopListOrder $order_by)
getUserToplistByWorkingtime(\ilObjTest $object, int $a_user_id)
getUserToplistByPercentage(\ilObjTest $object, int $a_user_id)