ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
ILIAS\Test\Participants\ParticipantTable Class Reference
+ Inheritance diagram for ILIAS\Test\Participants\ParticipantTable:
+ Collaboration diagram for ILIAS\Test\Participants\ParticipantTable:

Public Member Functions

 __construct (private readonly UIFactory $ui_factory, private readonly \ilUIService $ui_service, private readonly Language $lng, private readonly \ilTestAccess $test_access, private readonly RequestDataCollector $test_request, private readonly \ilTestParticipantAccessFilterFactory $participant_access_filter, private readonly ParticipantRepository $repository, private readonly ResultsDataFactory $results_data_factory, private readonly ResultsPresentationSettings $results_presentation_settings, private readonly \ilObjUser $current_user, private readonly \ilObjTest $test_object, private readonly ParticipantTableActions $table_actions)
 
 execute (URLBuilder $url_builder)
 
 getComponents (URLBuilder $url_builder, string $filter_url)
 
 getTotalRowCount (mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
 Mainly for the purpose of pagination-support, it is important to know about the total number of records available. More...
 
- Public Member Functions inherited from ILIAS\UI\Component\Table\DataRetrieval
 getRows (DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
 This is called by the table to retrieve rows; map data-records to rows using the $row_builder e.g. More...
 
 getTotalRowCount (mixed $additional_viewcontrol_data, mixed $filter_data, mixed $additional_parameters)
 Mainly for the purpose of pagination-support, it is important to know about the total number of records available. More...
 

Private Member Functions

 acquireParameters ($url_builder)
 
 getPostLoadFilters ()
 
 getPostLoadOrderFields ()
 
 getFilterComponent (string $action, ServerRequestInterface $request)
 
 getFilterFields (FieldFactory $field_factory)
 
 getTableComponent (ServerRequestInterface $request, ?array $filter)
 
 getColumns ()
 
 loadRecords (?array $filter, Order $order)
 
 buildAccessFilteredParticipantsList (array $records)
 
 getViewControlledRecords (?array $filter_data, Range $range, Order $order)
 
 filterRecords (iterable $records, ?array $filter_data)
 
 matchFilter (Participant $record, ?array $filter)
 
 orderRecords (iterable $records, Order $order)
 
 limitRecords (array $records, Range $range)
 

Private Attributes

const ID = 'pt'
 
iterable $records = null
 
bool $scoring_enabled = false
 

Detailed Description

Definition at line 39 of file ParticipantTable.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\Test\Participants\ParticipantTable::__construct ( private readonly UIFactory  $ui_factory,
private readonly \ilUIService  $ui_service,
private readonly Language  $lng,
private readonly \ilTestAccess  $test_access,
private readonly RequestDataCollector  $test_request,
private readonly \ilTestParticipantAccessFilterFactory  $participant_access_filter,
private readonly ParticipantRepository  $repository,
private readonly ResultsDataFactory  $results_data_factory,
private readonly ResultsPresentationSettings  $results_presentation_settings,
private readonly \ilObjUser  $current_user,
private readonly \ilObjTest  $test_object,
private readonly ParticipantTableActions  $table_actions 
)

Definition at line 45 of file ParticipantTable.php.

58 {
59 $this->scoring_enabled = $this->test_object->getGlobalSettings()->isManualScoringEnabled();
60 }

Member Function Documentation

◆ acquireParameters()

ILIAS\Test\Participants\ParticipantTable::acquireParameters (   $url_builder)
private

◆ buildAccessFilteredParticipantsList()

ILIAS\Test\Participants\ParticipantTable::buildAccessFilteredParticipantsList ( array  $records)
private
Parameters
array<Participant>$records
Returns
array<int>

Definition at line 493 of file ParticipantTable.php.

493 : array
494 {
495 $manage_access_filter = $this->participant_access_filter
496 ->getManageParticipantsUserFilter($this->test_object->getRefId());
497 $access_results_access_filter = $this->participant_access_filter
498 ->getAccessResultsUserFilter($this->test_object->getRefId());
499 $participant_ids = array_map(
500 fn(Participant $participant) => $participant->getUserId(),
502 );
503 return $manage_access_filter($participant_ids) + $access_results_access_filter($participant_ids);
504 }

References ILIAS\Test\Participants\Participant\getUserId().

+ Here is the call graph for this function:

◆ execute()

ILIAS\Test\Participants\ParticipantTable::execute ( URLBuilder  $url_builder)

Definition at line 62 of file ParticipantTable.php.

62 : ?Modal
63 {
64 return $this->table_actions->execute(...$this->acquireParameters($url_builder));
65 }

References ILIAS\Test\Participants\ParticipantTable\acquireParameters().

+ Here is the call graph for this function:

◆ filterRecords()

ILIAS\Test\Participants\ParticipantTable::filterRecords ( iterable  $records,
?array  $filter_data 
)
private

Definition at line 528 of file ParticipantTable.php.

528 : iterable
529 {
530 foreach ($records as $record) {
531 if ($this->matchFilter($record, $filter_data)) {
532 yield $record;
533 }
534 }
535 }
matchFilter(Participant $record, ?array $filter)

◆ getColumns()

ILIAS\Test\Participants\ParticipantTable::getColumns ( )
private
Returns
array<string, Column>

Definition at line 358 of file ParticipantTable.php.

358 : array
359 {
360 $column_factory = $this->ui_factory->table()->column();
361
362 $columns = [
363 'name' => $column_factory->text($this->lng->txt('name'))
364 ->withIsSortable(!$this->test_object->getAnonymity())
365 ];
366 if (!$this->test_object->getAnonymity()) {
367 $columns['login'] = $column_factory->text($this->lng->txt('login'))->withIsSortable(true);
368 }
369
370 $columns += [
371 'matriculation' => $column_factory->text($this->lng->txt('matriculation'))
372 ->withIsOptional(true, false)
373 ->withIsSortable(true),
374 'ip_range' => $column_factory->text($this->lng->txt('client_ip_range'))
375 ->withIsOptional(true, false)
376 ->withIsSortable(true),
377 'attempt_started_at' => $column_factory->date(
378 $this->lng->txt('tst_attempt_started'),
379 $this->current_user->getDateTimeFormat()
380 )->withIsSortable(true),
381 'total_time_on_task' => $column_factory->text($this->lng->txt('working_time'))
382 ->withIsOptional(true, false),
383 'total_attempts' => $column_factory->number($this->lng->txt('total_attempts'))
384 ->withIsOptional(true, false)
385 ->withIsSortable(true),
386 ];
387
388 $columns['status_of_attempt'] = $column_factory->text($this->lng->txt('status_of_attempt'))
389 ->withIsSortable(true);
390
391 if ($this->test_object->getEnableProcessingTime()) {
392 $columns['remaining_duration'] = $column_factory->text($this->lng->txt('remaining_duration'))
393 ->withIsOptional(true);
394 $columns['total_duration'] = $column_factory->text($this->lng->txt('total_duration'))
395 ->withIsOptional(true, false);
396 $columns['extra_time'] = $column_factory->text($this->lng->txt('extratime'))
397 ->withIsOptional(true, false);
398 }
399
400 if ($this->test_object->getMainSettings()->getTestBehaviourSettings()->getExamIdInTestAttemptEnabled()) {
401 $columns['id_of_attempt'] = $column_factory->text($this->lng->txt('exam_id_of_attempt'))
402 ->withIsOptional(true, false)
403 ->withIsSortable(true);
404 }
405
406 if ($this->test_access->checkParticipantsResultsAccess()) {
407 $columns['reached_points'] = $column_factory->text($this->lng->txt('tst_reached_points'))
408 ->withIsSortable(true);
409 $columns['nr_of_answered_questions'] = $column_factory->text($this->lng->txt('tst_answered_questions'))
410 ->withIsOptional(true, false)
411 ->withIsSortable(true);
412 $columns['percent_of_available_points'] = $column_factory->number($this->lng->txt('tst_percent_solved'))
413 ->withUnit('%')
414 ->withIsOptional(true, false)
415 ->withIsSortable(true);
416 $columns['test_passed'] = $column_factory->boolean(
417 $this->lng->txt('tst_passed'),
418 $this->ui_factory->symbol()->icon()->custom(
419 'assets/images/standard/icon_checked.svg',
420 $this->lng->txt('yes'),
421 'small'
422 ),
423 $this->ui_factory->symbol()->icon()->custom(
424 'assets/images/standard/icon_unchecked.svg',
425 $this->lng->txt('no'),
426 'small'
427 )
428 )->withIsSortable(true)
429 ->withOrderingLabels(
430 "{$this->lng->txt('tst_passed')}, {$this->lng->txt('yes')} {$this->lng->txt('order_option_first')}",
431 "{$this->lng->txt('tst_passed')}, {$this->lng->txt('no')} {$this->lng->txt('order_option_first')}"
432 );
433 $columns['mark'] = $column_factory->text($this->lng->txt('tst_mark'))
434 ->withIsOptional(true, false)
435 ->withIsSortable(true);
436 }
437 if ($this->scoring_enabled) {
438 $columns['scoring_finalized'] = $column_factory->boolean(
439 $this->lng->txt('finalized_evaluation'),
440 $this->ui_factory->symbol()->icon()->custom(
441 'assets/images/standard/icon_checked.svg',
442 $this->lng->txt('yes'),
443 'small'
444 ),
445 $this->ui_factory->symbol()->icon()->custom(
446 'assets/images/standard/icon_unchecked.svg',
447 $this->lng->txt('no'),
448 'small'
449 )
450 )->withIsOptional(true, false)
451 ->withIsSortable(true);
452 }
453
454 $columns['last_access'] = $column_factory->date(
455 $this->lng->txt('last_access'),
456 $this->current_user->getDateTimeFormat()
457 );
458
459 return $columns;
460 }

References ILIAS\Repository\lng().

+ Here is the call graph for this function:

◆ getComponents()

ILIAS\Test\Participants\ParticipantTable::getComponents ( URLBuilder  $url_builder,
string  $filter_url 
)
Returns
array<Component>

Definition at line 70 of file ParticipantTable.php.

70 : array
71 {
72 $filter = $this->getFilterComponent($filter_url, $this->test_request->getRequest());
73 $table = $this->getTableComponent(
74 $this->test_request->getRequest(),
75 $this->ui_service->filter()->getData($filter)
76 );
77
78 return [
79 $filter,
80 $table->withActions($this->table_actions->getEnabledActions(...$this->acquireParameters($url_builder)))
81 ];
82 }
getFilterComponent(string $action, ServerRequestInterface $request)
getTableComponent(ServerRequestInterface $request, ?array $filter)

References ILIAS\Test\Participants\ParticipantTable\getFilterComponent(), and ILIAS\Test\Participants\ParticipantTable\getTableComponent().

+ Here is the call graph for this function:

◆ getFilterComponent()

ILIAS\Test\Participants\ParticipantTable::getFilterComponent ( string  $action,
ServerRequestInterface  $request 
)
private

Definition at line 263 of file ParticipantTable.php.

263 : FilterComponent
264 {
265 $filter_inputs = [];
266 $is_input_initially_rendered = [];
267 $field_factory = $this->ui_factory->input()->field();
268
269 foreach ($this->getFilterFields($field_factory) as $filter_id => $filter) {
270 [$filter_inputs[$filter_id], $is_input_initially_rendered[$filter_id]] = $filter;
271 }
272
273 return $this->ui_service->filter()->standard(
274 "participant_filter_{$this->test_request->getRefId()}",
275 $action,
276 $filter_inputs,
277 $is_input_initially_rendered,
278 true,
279 true
280 );
281 }
getFilterFields(FieldFactory $field_factory)

Referenced by ILIAS\Test\Participants\ParticipantTable\getComponents().

+ Here is the caller graph for this function:

◆ getFilterFields()

ILIAS\Test\Participants\ParticipantTable::getFilterFields ( FieldFactory  $field_factory)
private
Parameters
FieldFactory$field_factory
Returns
array<string, FilterInput>

Definition at line 288 of file ParticipantTable.php.

288 : array
289 {
290 $yes_no_all_options = [
291 'true' => $this->lng->txt('yes'),
292 'false' => $this->lng->txt('no')
293 ];
294
295 $solution_options = [
296 'false' => $this->lng->txt('without_solution'),
297 'true' => $this->lng->txt('with_solution')
298 ];
299
300 $status_of_attempt_options = [
301 StatusOfAttempt::NOT_YET_STARTED->value => $this->lng->txt(StatusOfAttempt::NOT_YET_STARTED->value),
302 StatusOfAttempt::RUNNING->value => $this->lng->txt(StatusOfAttempt::RUNNING->value),
303 StatusOfAttempt::FINISHED_BY_UNKNOWN->value => $this->lng->txt(StatusOfAttempt::FINISHED_BY_UNKNOWN->value),
304 StatusOfAttempt::FINISHED_BY_ADMINISTRATOR->value => $this->lng->txt(StatusOfAttempt::FINISHED_BY_ADMINISTRATOR->value),
305 StatusOfAttempt::FINISHED_BY_CRONJOB->value => $this->lng->txt(StatusOfAttempt::FINISHED_BY_CRONJOB->value),
306 StatusOfAttempt::FINISHED_BY_DURATION->value => $this->lng->txt(StatusOfAttempt::FINISHED_BY_DURATION->value),
307 StatusOfAttempt::FINISHED_BY_PARTICIPANT->value => $this->lng->txt(StatusOfAttempt::FINISHED_BY_PARTICIPANT->value),
308 ];
309
310 $filters = [
311 'name' => [$field_factory->text($this->lng->txt('name')), true],
312 'login' => [$field_factory->text($this->lng->txt('login')), true],
313 'ip_range' => [$field_factory->text($this->lng->txt('client_ip_range')), true],
314 'solution' => [$field_factory->select($this->lng->txt('solutions'), $solution_options), true],
315 ];
316
317 if ($this->test_object->getEnableProcessingTime()) {
318 $filters['extra_time'] = [$field_factory->select($this->lng->txt('extratime'), $yes_no_all_options), true];
319 }
320
321 $filters['status_of_attempt'] = [
322 $field_factory->select($this->lng->txt('status_of_attempt'), $status_of_attempt_options),
323 true
324 ];
325
326 $filters['test_passed'] = [
327 $field_factory->select($this->lng->txt('tst_passed'), $yes_no_all_options),
328 true
329 ];
330
331 if ($this->scoring_enabled) {
332 $filters['scoring_finalized'] = [
333 $field_factory->select($this->lng->txt('finalized_evaluation'), $yes_no_all_options),
334 true
335 ];
336 }
337
338 return $filters;
339 }
return true

References ILIAS\Repository\lng(), and true.

+ Here is the call graph for this function:

◆ getPostLoadFilters()

ILIAS\Test\Participants\ParticipantTable::getPostLoadFilters ( )
private
Returns
array<string, \Closure>

Definition at line 182 of file ParticipantTable.php.

182 : array
183 {
184 return [
185 'solution' => fn(string $value, Participant $record) =>
186 $value === 'true' ? $record->hasAnsweredQuestionsForScoredAttempt() : !$record->hasAnsweredQuestionsForScoredAttempt(),
187 'status_of_attempt' => fn(string $value, Participant $record) =>
188 ($value === StatusOfAttempt::NOT_YET_STARTED->value && $record->getAttemptOverviewInformation()?->getStatusOfAttempt() === null) ||
189 $value === $record->getAttemptOverviewInformation()?->getStatusOfAttempt()->value,
190 'test_passed' => fn(string $value, Participant $record) => $value === 'true'
191 ? $record->getAttemptOverviewInformation()?->hasPassingMark() === true
192 : $record->getAttemptOverviewInformation()?->hasPassingMark() !== true,
193 'scoring_finalized' => fn(string $value, Participant $record) => $value === 'true'
194 ? $record->isScoringFinalized() == true
195 : $record->isScoringFinalized() === false
196 ];
197 }

References ILIAS\Test\Participants\Participant\getAttemptOverviewInformation(), ILIAS\Test\Participants\Participant\hasAnsweredQuestionsForScoredAttempt(), ILIAS\Test\Participants\Participant\isScoringFinalized(), and true.

+ Here is the call graph for this function:

◆ getPostLoadOrderFields()

ILIAS\Test\Participants\ParticipantTable::getPostLoadOrderFields ( )
private
Returns
array<string, \Closure>

Definition at line 202 of file ParticipantTable.php.

202 : array
203 {
204 $processing_time = $this->test_object->getProcessingTimeInSeconds();
205 $reset_time_on_new_attempt = $this->test_object->getResetProcessingTime();
206
207 return [
208 'attempt_started_at' => static fn(Participant $a, Participant $b) => $a->getFirstAccess() <=> $b->getFirstAccess(),
209 'total_duration' => static fn(
212 ) => $a->getTotalDuration($processing_time) <=> $b->getTotalDuration($processing_time),
213 'remaining_duration' => static fn(
216 ) => $a->getRemainingDuration($processing_time, $reset_time_on_new_attempt)
217 <=> $b->getRemainingDuration($processing_time, $reset_time_on_new_attempt),
218 'last_access' => static fn(Participant $a, Participant $b) => $a->getLastAccess() <=> $b->getLastAccess(),
219 'status_of_attempt' => static fn(
222 ) => $a->getAttemptOverviewInformation()?->getStatusOfAttempt()
223 <=> $b->getAttemptOverviewInformation()?->getStatusOfAttempt(),
224 'reached_points' => static fn(
227 ) => $a->getAttemptOverviewInformation()?->getReachedPoints()
228 <=> $b->getAttemptOverviewInformation()?->getReachedPoints(),
229 'nr_of_answered_questions' => static fn(
232 ) => $a->getAttemptOverviewInformation()?->getNrOfAnsweredQuestions()
233 <=> $b->getAttemptOverviewInformation()?->getNrOfAnsweredQuestions(),
234 'percent_of_available_points' => static fn(
237 ) => $a->getAttemptOverviewInformation()?->getReachedPointsInPercent()
238 <=> $b->getAttemptOverviewInformation()?->getReachedPointsInPercent(),
239 'test_passed' => static fn(
242 ) => $a->getAttemptOverviewInformation()?->hasPassingMark()
243 <=> $b->getAttemptOverviewInformation()?->hasPassingMark(),
244 'mark' => static fn(
247 ) => $a->getAttemptOverviewInformation()?->getMark() <=> $b->getAttemptOverviewInformation()?->getMark(),
248 'matriculation' => static fn(
251 ) => $a->getMatriculation() <=> $b->getMatriculation(),
252 'id_of_attempt' => static fn(
255 ) => $a->getAttemptOverviewInformation()?->getExamId() <=> $b->getAttemptOverviewInformation()?->getExamId(),
256 'total_time_on_task' => static fn(
259 ) => $a->getAttemptOverviewInformation()?->getTotalTimeOnTask() <=> $b->getAttemptOverviewInformation()?->getTotalTimeOnTask()
260 ];
261 }
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples

References Vendor\Package\$a, and Vendor\Package\$b.

◆ getTableComponent()

ILIAS\Test\Participants\ParticipantTable::getTableComponent ( ServerRequestInterface  $request,
?array  $filter 
)
private

Definition at line 341 of file ParticipantTable.php.

342 {
343 return $this->ui_factory
344 ->table()
345 ->data(
346 $this,
347 $this->lng->txt('list_of_participants'),
348 $this->getColumns(),
349 )
350 ->withId(self::ID)
351 ->withRequest($request)
352 ->withFilter($filter);
353 }

References ILIAS\Repository\lng().

Referenced by ILIAS\Test\Participants\ParticipantTable\getComponents().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getTotalRowCount()

ILIAS\Test\Participants\ParticipantTable::getTotalRowCount ( mixed  $additional_viewcontrol_data,
mixed  $filter_data,
mixed  $additional_parameters 
)

Mainly for the purpose of pagination-support, it is important to know about the total number of records available.

Given the nature of a DataTable, which is, opposite to a PresentationTable, rather administrative than explorative, this information will increase user experience quite a bit. However, you may return null, if the call is to costly, but expect the View Control to look a little different in this case.

Make sure that potential filters or user restrictions are being applied to the count.

Implements ILIAS\UI\Component\Table\DataRetrieval.

Definition at line 84 of file ParticipantTable.php.

88 : ?int {
89 return $this->repository->countParticipants($this->test_object->getTestId(), $filter_data);
90 }

◆ getViewControlledRecords()

ILIAS\Test\Participants\ParticipantTable::getViewControlledRecords ( ?array  $filter_data,
Range  $range,
Order  $order 
)
private
Returns
iterable<Participant>

Definition at line 510 of file ParticipantTable.php.

510 : iterable
511 {
512 return $this->limitRecords(
513 $this->orderRecords(
514 $this->filterRecords(
515 $this->results_data_factory->addAttemptOverviewInformationToParticipants(
516 $this->results_presentation_settings,
517 $this->test_object,
518 $this->loadRecords($filter_data, $order)
519 ),
520 $filter_data
521 ),
522 $order
523 ),
524 $range
525 );
526 }
filterRecords(iterable $records, ?array $filter_data)
orderRecords(iterable $records, Order $order)
limitRecords(array $records, Range $range)

References ILIAS\UI\Implementation\Component\Table\$range.

◆ limitRecords()

ILIAS\Test\Participants\ParticipantTable::limitRecords ( array  $records,
Range  $range 
)
private

Definition at line 579 of file ParticipantTable.php.

579 : array
580 {
581 return array_slice($records, $range->getStart(), $range->getLength());
582 }

References ILIAS\UI\Implementation\Component\Table\$range, ILIAS\Data\Range\getLength(), and ILIAS\Data\Range\getStart().

+ Here is the call graph for this function:

◆ loadRecords()

ILIAS\Test\Participants\ParticipantTable::loadRecords ( ?array  $filter,
Order  $order 
)
private

Definition at line 462 of file ParticipantTable.php.

462 : iterable
463 {
464 if ($this->records !== null) {
465 return $this->records;
466 }
467
468 $records = iterator_to_array(
469 $this->repository->getParticipants(
470 $this->test_object->getTestId(),
471 $filter,
472 null,
473 $order
474 )
475 );
476
477 $this->records = array_filter(
478 $records,
479 fn(Participant $participant) => in_array(
480 $participant->getUserId(),
481 $this->buildAccessFilteredParticipantsList($records)
482 )
483 );
484
485 return $this->records;
486 }

References ILIAS\Test\Participants\Participant\getUserId(), and ILIAS\UI\examples\Deck\repository().

+ Here is the call graph for this function:

◆ matchFilter()

ILIAS\Test\Participants\ParticipantTable::matchFilter ( Participant  $record,
?array  $filter 
)
private

Definition at line 537 of file ParticipantTable.php.

537 : bool
538 {
539 if ($filter === null) {
540 return true;
541 }
542
543 $post_load_filters = $this->getPostLoadFilters();
544 $allow = true;
545
546 foreach ($filter as $key => $value) {
547 if (!$value) {
548 continue;
549 }
550
551 $post_load_filter = $post_load_filters[$key] ?? fn() => true;
552 $allow = $allow && $post_load_filter($value, $record);
553 }
554
555 return $allow;
556 }

◆ orderRecords()

ILIAS\Test\Participants\ParticipantTable::orderRecords ( iterable  $records,
Order  $order 
)
private

Definition at line 558 of file ParticipantTable.php.

558 : array
559 {
560 $post_load_order_fields = $this->getPostLoadOrderFields();
561 $records = iterator_to_array($records);
562
563 uasort($records, static function (Participant $a, Participant $b) use ($order, $post_load_order_fields) {
564 foreach ($order->get() as $subject => $direction) {
565 $post_load_order_field = $post_load_order_fields[$subject] ?? fn() => 0;
566 $index = $post_load_order_field($a, $b);
567
568 if ($index !== 0) {
569 return $direction === 'DESC' ? $index * -1 : $index;
570 }
571 }
572
573 return 0;
574 });
575
576 return $records;
577 }

References Vendor\Package\$a, Vendor\Package\$b, and ILIAS\Data\Order\get().

+ Here is the call graph for this function:

Field Documentation

◆ $records

iterable ILIAS\Test\Participants\ParticipantTable::$records = null
private

Definition at line 42 of file ParticipantTable.php.

◆ $scoring_enabled

bool ILIAS\Test\Participants\ParticipantTable::$scoring_enabled = false
private

Definition at line 43 of file ParticipantTable.php.

◆ ID

const ILIAS\Test\Participants\ParticipantTable::ID = 'pt'
private

Definition at line 41 of file ParticipantTable.php.


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