ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ILIAS\Test\Participants\ParticipantRepository Class Reference
+ Collaboration diagram for ILIAS\Test\Participants\ParticipantRepository:

Public Member Functions

 __construct (private readonly \ilDBInterface $database)
 
 countParticipants (int $test_id, ?array $filter)
 
 getParticipants (int $test_id, ?array $filter=null, ?Range $range=null, ?Order $order=null)
 
 getParticipantByActiveId (int $test_id, int $active_id)
 
 getParticipantByUserId (int $test_id, int $user_id)
 
 updateExtraTime (Participant $participant)
 
 updateIpRange (array $participants)
 
 lookupTestIdByActiveId (int $active_id)
 
 removeParticipants (array $selected_participants)
 
 getFirstAndLastVisitForActiveId (int $active_id)
 
 removeExtraTimeByUserId (int $test_id, array $user_ids)
 

Private Member Functions

 fetchParticipant (string $query, array $types, array $values)
 
 applyFilter (?array $filter, array $where, array $types, array $values)
 
 applyOrder (?Order $order)
 
 isFilterSet (array $filter, string $key)
 
 getBaseQuery ()
 
 arrayToObject (array $row)
 
 getActiveParticipantsQuery ()
 
 getInvitedParticipantsQuery ()
 

Detailed Description

Definition at line 26 of file ParticipantRepository.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\Test\Participants\ParticipantRepository::__construct ( private readonly \ilDBInterface  $database)

Definition at line 28 of file ParticipantRepository.php.

30 {
31 }

Member Function Documentation

◆ applyFilter()

ILIAS\Test\Participants\ParticipantRepository::applyFilter ( ?array  $filter,
array  $where,
array  $types,
array  $values 
)
private
Parameters
array<string,mixed>$filter
array<int,string>$where
array<int,string>$types
array<int,mixed>$values
Returns
array

Definition at line 245 of file ParticipantRepository.php.

250 : array {
251 if ($filter === null) {
252 return [$where, $types, $values];
253 }
254
255 if ($this->isFilterSet($filter, 'name')) {
256 $where[] = '(firstname LIKE %s OR lastname LIKE %s)';
257 $types = array_merge($types, ['string', 'string']);
258 $values = array_merge($values, ["%{$filter['name']}%", "%{$filter['name']}%"]);
259 }
260
261 if ($this->isFilterSet($filter, 'login')) {
262 $where[] = '(login LIKE %s)';
263 $types = array_merge($types, ['string']);
264 $values = array_merge($values, ["%{$filter['login']}%"]);
265 }
266
267 if ($this->isFilterSet($filter, 'extra_time')) {
268 if ($filter['extra_time'] === 'true') {
269 $where[] = '(extra_time > 0 AND extra_time IS NOT NULL)';
270 } else {
271 $where[] = '(extra_time = 0 OR extra_time IS NULL)';
272 }
273 }
274
275 if ($this->isFilterSet($filter, 'ip_range')) {
276 $where[] = '(ip_range_from LIKE %s OR ip_range_to LIKE %s)';
277 $types = array_merge($types, ['string', 'string']);
278 $values = array_merge($values, ["%{$filter['ip_range']}%", "%{$filter['ip_range']}%"]);
279 }
280
281 return [$where, $types, $values];
282 }

Referenced by ILIAS\Test\Participants\ParticipantRepository\countParticipants().

+ Here is the caller graph for this function:

◆ applyOrder()

ILIAS\Test\Participants\ParticipantRepository::applyOrder ( ?Order  $order)
private

Definition at line 284 of file ParticipantRepository.php.

284 : string
285 {
286 if ($order === null) {
287 return '';
288 }
289 $order_by = [];
290 foreach ($order->get() as $subject => $direction) {
291 $order_by[] = match ($subject) {
292 'name' => "lastname {$direction}, firstname {$direction}",
293 'login' => "login {$direction}",
294 'ip_range' => "ip_range_from {$direction}, ip_range_to {$direction}",
295 'total_attempts' => "tries {$direction}",
296 'extra_time' => "extra_time {$direction}",
297 default => null
298 };
299 }
300 return trim(join(', ', array_filter($order_by)));
301 }

References ILIAS\Data\Order\get().

+ Here is the call graph for this function:

◆ arrayToObject()

ILIAS\Test\Participants\ParticipantRepository::arrayToObject ( array  $row)
private

Definition at line 322 of file ParticipantRepository.php.

323 {
324 return new Participant(
325 $row['user_fi'],
326 $row['active_id'],
327 $row['test_fi'],
328 $row['anonymous_id'],
329 $row['firstname'] ?? '',
330 $row['lastname'] ?? '',
331 $row['login'] ?? '',
332 $row['matriculation'] ?? '',
333 $row['extra_time'] ?? 0,
334 $row['tries'] ?? 0,
335 $row['ip_range_from'],
336 $row['ip_range_to'],
337 $row['invitation_date'],
338 $row['submitted'] === 1,
339 $row['last_started_pass'],
340 $row['last_finished_pass'],
341 $row['unfinished_attempts'] === 1,
342 $row['first_access'] === null ? null : new \DateTimeImmutable($row['first_access']),
343 $row['last_access'] === null ? null : new \DateTimeImmutable($row['last_access']),
344 (bool) $row['scoring_finalized']
345 );
346 }

◆ countParticipants()

ILIAS\Test\Participants\ParticipantRepository::countParticipants ( int  $test_id,
?array  $filter 
)
Parameters
int$test_id
array<string,mixed>$filter
Returns
int

Definition at line 39 of file ParticipantRepository.php.

39 : int
40 {
41 $query = "
42 SELECT COUNT(participants.user_fi) as number_of_participants
43 FROM (
44 ({$this->getActiveParticipantsQuery()})
45 UNION
46 ({$this->getInvitedParticipantsQuery()})
47 ) participants
48 ";
49 [$where, $types, $values] = $this->applyFilter($filter, [], ['integer', 'integer'], [$test_id, $test_id]);
50
51 if (!empty($where)) {
52 $where = join(' AND ', $where);
53 $query .= " WHERE $where";
54 }
55
56 $statement = $this->database->queryF($query, $types, $values);
57 $result = $this->database->fetchAssoc($statement);
58
59 return $result['number_of_participants'] ?? 0;
60 }
applyFilter(?array $filter, array $where, array $types, array $values)

References ILIAS\Test\Participants\ParticipantRepository\applyFilter(), and ILIAS\Repository\database().

+ Here is the call graph for this function:

◆ fetchParticipant()

ILIAS\Test\Participants\ParticipantRepository::fetchParticipant ( string  $query,
array  $types,
array  $values 
)
private
Parameters
array<int,string>$types
array<int,mixed>$values

Definition at line 225 of file ParticipantRepository.php.

225 : ?Participant
226 {
227 $statement = $this->database->queryF($query, $types, $values);
228 $row = $this->database->fetchAssoc($statement);
229
230 if (!$row) {
231 return null;
232 }
233
234 return $this->arrayToObject($row);
235 }

References ILIAS\Repository\database().

+ Here is the call graph for this function:

◆ getActiveParticipantsQuery()

ILIAS\Test\Participants\ParticipantRepository::getActiveParticipantsQuery ( )
private
Returns
string

Definition at line 351 of file ParticipantRepository.php.

351 : string
352 {
353 return "
354 SELECT ta.active_id,
355 ta.user_fi,
356 ta.test_fi,
357 ta.anonymous_id,
358 ta.tries,
359 ta.submitted,
360 ta.last_finished_pass,
361 ta.last_started_pass,
362 COALESCE(ta.last_started_pass, -1) <> COALESCE(ta.last_finished_pass, -1) as unfinished_attempts,
363 ud.firstname,
364 ud.lastname,
365 ud.login,
366 ud.matriculation,
367 (SELECT MIN(started) FROM tst_times WHERE active_fi = ta.active_id) as first_access,
368 (SELECT MAX(finished) FROM tst_times WHERE active_fi = ta.active_id) as last_access,
369 tatime.additionaltime extra_time,
370 tinvited.ip_range_from,
371 tinvited.ip_range_to,
372 tinvited.tstamp as invitation_date
373 FROM tst_active ta
374 LEFT JOIN usr_data ud
375 ON ud.usr_id = ta.user_fi
376 LEFT JOIN tst_addtime tatime
377 ON tatime.user_fi = ta.user_fi
378 AND tatime.test_fi = ta.test_fi
379 LEFT JOIN tst_invited_user tinvited
380 ON tinvited.test_fi = ta.test_fi
381 AND tinvited.user_fi = ta.user_fi
382 WHERE ta.test_fi = %s
383 ";
384 }

◆ getBaseQuery()

ILIAS\Test\Participants\ParticipantRepository::getBaseQuery ( )
private

Definition at line 309 of file ParticipantRepository.php.

309 : string
310 {
311 return "
312 SELECT participants.*, manscoring_done.done as scoring_finalized
313 FROM (
314 ({$this->getActiveParticipantsQuery()})
315 UNION
316 ({$this->getInvitedParticipantsQuery()})
317 ) as participants
318 LEFT JOIN manscoring_done ON manscoring_done.active_id = participants.active_id
319 ";
320 }

◆ getFirstAndLastVisitForActiveId()

ILIAS\Test\Participants\ParticipantRepository::getFirstAndLastVisitForActiveId ( int  $active_id)

Definition at line 197 of file ParticipantRepository.php.

197 : array
198 {
199 $times = $this->database->fetchAssoc(
200 $this->database->queryF(
201 'SELECT MIN(started) AS first_access, MAX(finished) AS last_access '
202 . 'FROM tst_times WHERE active_fi = %s',
203 ['integer'],
204 [$active_id]
205 )
206 );
207
208 $start_time = null;
209 if ($times['first_access'] !== null) {
210 $start_time = new \DateTimeImmutable($times['first_access']);
211 }
212
213 $end_time = null;
214 if ($times['last_access'] !== null) {
215 $end_time = new \DateTimeImmutable($times['last_access']);
216 }
217
218 return ['first_access' => $start_time, 'last_access' => $end_time];
219 }

References ILIAS\Repository\database().

+ Here is the call graph for this function:

◆ getInvitedParticipantsQuery()

ILIAS\Test\Participants\ParticipantRepository::getInvitedParticipantsQuery ( )
private
Returns
string

Definition at line 389 of file ParticipantRepository.php.

389 : string
390 {
391 return "
392 SELECT ta.active_id,
393 tinvited.user_fi,
394 tinvited.test_fi,
395 ta.anonymous_id,
396 ta.tries,
397 ta.submitted,
398 ta.last_finished_pass,
399 ta.last_started_pass,
400 COALESCE(ta.last_started_pass, -1) <> COALESCE(ta.last_finished_pass, -1) as unfinished_attempts,
401 ud.firstname,
402 ud.lastname,
403 ud.login,
404 ud.matriculation,
405 NULL as first_access,
406 NULL as last_access,
407 tatime.additionaltime extra_time,
408 tinvited.ip_range_from,
409 tinvited.ip_range_to,
410 tinvited.tstamp as invitation_date
411 FROM tst_invited_user tinvited
412 LEFT JOIN usr_data ud
413 ON ud.usr_id = tinvited.user_fi
414 LEFT JOIN tst_addtime tatime
415 ON tatime.user_fi = tinvited.user_fi
416 AND tatime.test_fi = tinvited.test_fi
417 LEFT JOIN tst_active ta
418 ON tinvited.test_fi = ta.test_fi
419 AND tinvited.user_fi = ta.user_fi
420 WHERE tinvited.test_fi = %s AND ta.active_id IS NULL
421 ";
422 }

◆ getParticipantByActiveId()

ILIAS\Test\Participants\ParticipantRepository::getParticipantByActiveId ( int  $test_id,
int  $active_id 
)

Definition at line 100 of file ParticipantRepository.php.

100 : ?Participant
101 {
102 return $this->fetchParticipant(
103 "{$this->getBaseQuery()} WHERE active_id = %s",
104 ['integer', 'integer', 'integer'],
105 [$test_id, $test_id, $active_id]
106 );
107 }
fetchParticipant(string $query, array $types, array $values)

◆ getParticipantByUserId()

ILIAS\Test\Participants\ParticipantRepository::getParticipantByUserId ( int  $test_id,
int  $user_id 
)

Definition at line 109 of file ParticipantRepository.php.

109 : ?Participant
110 {
111 return $this->fetchParticipant(
112 "{$this->getBaseQuery()} WHERE user_fi = %s",
113 ['integer', 'integer', 'integer'],
114 [$test_id, $test_id, $user_id]
115 );
116 }

References $user_id.

◆ getParticipants()

ILIAS\Test\Participants\ParticipantRepository::getParticipants ( int  $test_id,
?array  $filter = null,
?Range  $range = null,
?Order  $order = null 
)
Parameters
array<string,mixed>$filter

Definition at line 65 of file ParticipantRepository.php.

70 : \Generator {
71 $query = $this->getBaseQuery();
72 [$where, $types, $values] = $this->applyFilter(
73 $filter,
74 [],
75 ['integer', 'integer'],
76 [$test_id, $test_id]
77 );
78
79 if ($where !== []) {
80 $where = join(' AND ', $where);
81 $query .= " WHERE {$where}";
82 }
83
84 $order_by = $this->applyOrder($order);
85
86 if ($order_by !== '') {
87 $query .= " ORDER BY {$order_by}";
88 }
89 if ($range !== null) {
90 $query .= " LIMIT {$range->getStart()}, {$range->getLength()}";
91 }
92
93 $statement = $this->database->queryF($query, $types, $values);
94
95 while ($row = $this->database->fetchAssoc($statement)) {
96 yield $this->arrayToObject($row);
97 }
98 }

◆ isFilterSet()

ILIAS\Test\Participants\ParticipantRepository::isFilterSet ( array  $filter,
string  $key 
)
private

Definition at line 303 of file ParticipantRepository.php.

303 : bool
304 {
305 return isset($filter[$key]) && trim($filter[$key]) !== "";
306 }

◆ lookupTestIdByActiveId()

ILIAS\Test\Participants\ParticipantRepository::lookupTestIdByActiveId ( int  $active_id)

Definition at line 149 of file ParticipantRepository.php.

149 : int
150 {
151 $result = $this->database->queryF(
152 'SELECT test_fi FROM tst_active WHERE active_id = %s',
153 ['integer'],
154 [$active_id]
155 );
156 $test_id = -1;
157 if ($this->database->numRows($result) > 0) {
158 $row = $this->database->fetchAssoc($result);
159 $test_id = (int) $row['test_fi'];
160 }
161
162 return $test_id;
163 }

References ILIAS\Repository\database(), and ILIAS\Repository\int().

+ Here is the call graph for this function:

◆ removeExtraTimeByUserId()

ILIAS\Test\Participants\ParticipantRepository::removeExtraTimeByUserId ( int  $test_id,
array  $user_ids 
)

Definition at line 424 of file ParticipantRepository.php.

424 : void
425 {
426 $in_user_fis = $this->database->in(
427 'user_fi',
428 $user_ids,
429 false,
431 );
432 $this->database->manipulate("DELETE FROM tst_addtime WHERE test_fi = $test_id AND $in_user_fis");
433 }

References ILIAS\Repository\database(), and ilDBConstants\T_INTEGER.

+ Here is the call graph for this function:

◆ removeParticipants()

ILIAS\Test\Participants\ParticipantRepository::removeParticipants ( array  $selected_participants)
Parameters
array<Participant>$selected_participants

Definition at line 169 of file ParticipantRepository.php.

169 : void
170 {
171 $this->database->manipulate(
172 "DELETE FROM tst_invited_user WHERE test_fi = {$selected_participants[0]->getTestId()} AND "
173 . $this->database->in(
174 'user_fi',
175 array_map(
176 fn(Participant $participant): int => $participant->getUserId(),
177 $selected_participants
178 ),
179 false,
181 )
182 );
183 $this->database->manipulate(
184 "DELETE FROM tst_addtime WHERE test_fi = {$selected_participants[0]->getTestId()} AND "
185 . $this->database->in(
186 'user_fi',
187 array_map(
188 fn(Participant $participant): int => $participant->getUserId(),
189 $selected_participants
190 ),
191 false,
193 )
194 );
195 }

References ILIAS\Repository\database(), ILIAS\Test\Participants\Participant\getUserId(), and ilDBConstants\T_INTEGER.

+ Here is the call graph for this function:

◆ updateExtraTime()

ILIAS\Test\Participants\ParticipantRepository::updateExtraTime ( Participant  $participant)

Definition at line 118 of file ParticipantRepository.php.

118 : void
119 {
120 $this->database->manipulatef(
121 "INSERT INTO tst_addtime (user_fi, test_fi, additionaltime, tstamp) VALUES (%s, %s, %s, %s)
122 ON DUPLICATE KEY UPDATE tstamp = %s, additionaltime = %s",
123 ['integer', 'integer', 'integer','timestamp','timestamp', 'integer'],
124 [$participant->getUserId(), $participant->getTestId(), $participant->getExtraTime(), time(), time(), $participant->getExtraTime()]
125 );
126 }

References ILIAS\Repository\database(), ILIAS\Test\Participants\Participant\getExtraTime(), ILIAS\Test\Participants\Participant\getTestId(), and ILIAS\Test\Participants\Participant\getUserId().

+ Here is the call graph for this function:

◆ updateIpRange()

ILIAS\Test\Participants\ParticipantRepository::updateIpRange ( array  $participants)
Parameters
array<Participant>$participants

Definition at line 131 of file ParticipantRepository.php.

131 : void
132 {
133 foreach ($participants as $participant) {
134 $this->database->replace(
135 'tst_invited_user',
136 [
137 'test_fi' => [\ilDBConstants::T_INTEGER, $participant->getTestId()],
138 'user_fi' => [\ilDBConstants::T_INTEGER, $participant->getUserId()]
139 ],
140 [
141 'ip_range_from' => [\ilDBConstants::T_TEXT, $participant->getClientIpFrom()],
142 'ip_range_to' => [\ilDBConstants::T_TEXT, $participant->getClientIpTo()],
143 'tstamp' => [\ilDBConstants::T_INTEGER, time()]
144 ]
145 );
146 }
147 }

References ILIAS\Repository\database(), ilDBConstants\T_INTEGER, and ilDBConstants\T_TEXT.

+ Here is the call graph for this function:

The documentation for this class was generated from the following file: