ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
TestTopListRepository.php
Go to the documentation of this file.
1<?php
2
19declare(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 $this->db->setLimit($object->getHighscoreTopNum(), 0);
33 $result = $this->db->query(
34 '
35 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
36 FROM object_reference
37 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
38 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
39 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
40 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi 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($object->getRefId(), 'integer') .
43 ($order_by === TopListOrder::BY_TIME
44 ? ' ORDER BY tst_pass_result.workingtime DESC, tstamp ASC'
45 : ' ORDER BY percentage DESC, tstamp ASC')
46 );
47
48 $i = 1;
49 while ($row = $this->db->fetchAssoc($result)) {
50 $row['rank'] = $i;
51 $i += 1;
52 yield $row;
53 }
54 }
55
56 public function getUserToplistByPercentage(\ilObjTest $object, int $a_user_id): \Generator
57 {
58 $a_test_ref_id = $object->getRefId();
59 $better_participants = $this->db->fetchObject(
60 $this->db->query(
61 '
62 SELECT COUNT(tst_pass_result.workingtime) cnt
63 FROM object_reference
64 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
65 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
66 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
67 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
68 AND tst_pass_result.pass = tst_result_cache.pass
69 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
70 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
71 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
72 AND round(reached_points/max_points*100) >=
73 (
74 SELECT round(reached_points/max_points*100)
75 FROM object_reference
76 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
77 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
78 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
79 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
80 AND tst_pass_result.pass = tst_result_cache.pass
81 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
82 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
83 )
84 '
85 )
86 )->cnt;
87
88 $total_participants = $this->db->fetchObject(
89 $this->db->query("
90 SELECT COUNT(tst_pass_result.workingtime) cnt
91 FROM object_reference
92 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
93 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
94 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
95 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
96 AND tst_pass_result.pass = tst_result_cache.pass
97 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
98 WHERE object_reference.ref_id = {$this->db->quote($a_test_ref_id, 'integer')}
99 ")
100 )->cnt;
101
102 [$offset, $amount] = $this->calculateLimits(
103 $object->getHighscoreTopNum(),
104 $better_participants,
105 $total_participants
106 );
107
108 $result = $this->db->query("
109 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage ,
110 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
111 FROM object_reference
112 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
113 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
114 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
115 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
116 AND tst_pass_result.pass = tst_result_cache.pass
117 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
118 WHERE object_reference.ref_id = {$this->db->quote($a_test_ref_id, 'integer')}
119 ORDER BY round(reached_points/max_points*100) DESC, tstamp ASC
120 LIMIT {$amount} OFFSET {$offset}
121 ");
122
123 if ($offset > 0) {
124 yield $this->buildEmptyItem();
125 }
126
127 $i = $offset + 1;
128 while ($row = $this->db->fetchAssoc($result)) {
129 $row['rank'] = $i;
130 $i += 1;
131 yield $row;
132 }
133
134 if ($total_participants > $offset + $amount) {
135 yield $this->buildEmptyItem();
136 }
137 }
138
139 public function getUserToplistByWorkingtime(\ilObjTest $object, int $a_user_id): \Generator
140 {
141
142 $a_test_ref_id = $object->getRefId();
143 $better_participants = $this->db->fetchObject(
144 $this->db->query(
145 '
146 SELECT COUNT(tst_pass_result.workingtime) cnt
147 FROM object_reference
148 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
149 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
150 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
151 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
152 AND tst_pass_result.pass = tst_result_cache.pass
153 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
154 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
155 AND tst_active.user_fi != ' . $this->db->quote($a_user_id, 'integer') . '
156 AND workingtime <
157 (
158 SELECT workingtime
159 FROM object_reference
160 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
161 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
162 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
163 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
164 AND tst_pass_result.pass = tst_result_cache.pass
165 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer') . '
166 AND tst_active.user_fi = ' . $this->db->quote($a_user_id, 'integer') . '
167 )
168 '
169 )
170 )->cnt;
171
172 $total_participants = $this->db->fetchObject(
173 $this->db->query(
174 '
175 SELECT COUNT(tst_pass_result.workingtime) cnt
176 FROM object_reference
177 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
178 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
179 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
180 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
181 AND tst_pass_result.pass = tst_result_cache.pass
182 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
183 WHERE object_reference.ref_id = ' . $this->db->quote($a_test_ref_id, 'integer')
184 )
185 )->cnt;
186
187 [$offset, $amount] = $this->calculateLimits(
188 $object->getHighscoreTopNum(),
189 $better_participants,
190 $total_participants
191 );
192
193 $result = $this->db->query("
194 SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage,
195 tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname
196 FROM object_reference
197 INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi
198 INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi
199 INNER JOIN tst_result_cache ON tst_active.active_id = tst_result_cache.active_fi
200 INNER JOIN tst_pass_result ON tst_active.active_id = tst_pass_result.active_fi
201 AND tst_pass_result.pass = tst_result_cache.pass
202 INNER JOIN usr_data ON usr_data.usr_id = tst_active.user_fi
203 WHERE object_reference.ref_id = {$this->db->quote($a_test_ref_id, 'integer')}
204 ORDER BY workingtime ASC
205 LIMIT {$amount} OFFSET {$offset}
206 ");
207
208 if ($offset > 0) {
209 yield $this->buildEmptyItem();
210 }
211
212 $i = $offset + 1;
213 while ($row = $this->db->fetchAssoc($result)) {
214 $row['rank'] = $i;
215 $i += 1;
216 yield $row;
217 }
218
219 if ($total_participants > $offset + $amount) {
220 yield $this->buildEmptyItem();
221 }
222 }
223
224 private function calculateLimits(
225 int $pax_to_show,
226 int $better_pax,
227 int $total_pax
228 ): array {
229 if ($total_pax < $pax_to_show) {
230 return [0, $total_pax];
231 }
232
233 $pax_to_show_on_each_side = floor($pax_to_show / 2);
234 $offset = $better_pax - $pax_to_show_on_each_side;
235 if ($offset < 0) {
236 $offset = 0;
237 }
238 $end = $offset + $pax_to_show;
239
240 if ($end < $total_pax) {
241 return [$offset, $pax_to_show];
242 }
243
244 return [$total_pax - $pax_to_show, $pax_to_show];
245 }
246
247 private function buildEmptyItem(): array
248 {
249 return [
250 'rank' => '...',
251 'is_actor' => false,
252 'participant' => '',
253 'achieved' => '',
254 'score' => '',
255 'percentage' => null,
256 'time' => ''
257 ];
258 }
259}
getGeneralToplist(\ilObjTest $object, TopListOrder $order_by)
calculateLimits(int $pax_to_show, int $better_pax, int $total_pax)
__construct(private readonly \ilDBInterface $db)
getUserToplistByWorkingtime(\ilObjTest $object, int $a_user_id)
getUserToplistByPercentage(\ilObjTest $object, int $a_user_id)
getHighscoreTopNum(int $a_retval=10)
Gets the number of entries which are to be shown in the top-rankings table.
Interface ilDBInterface.
if(!file_exists('../ilias.ini.php'))