Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ private function getParticipantTable(): ParticipantTable
$this->ui_factory,
$this->ui_service,
$this->lng,
$this->ctrl,
$this->test_access,
$this->testrequest,
$this->participant_access_filter,
Expand Down
6 changes: 6 additions & 0 deletions components/ILIAS/Test/lang/assessment.pot
Original file line number Diff line number Diff line change
Expand Up @@ -3812,6 +3812,12 @@ msgstr ""
msgid "tst_participant_fullname_pattern"
msgstr ""

msgid "tst_participant_last_attempts"
msgstr ""

msgid "tst_participant_scored_attempts"
msgstr ""

msgid "tst_participant_status"
msgstr ""

Expand Down
6 changes: 6 additions & 0 deletions components/ILIAS/Test/lang/assessment_de.po
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,12 @@ msgstr "Teilnehmer"
msgid "tst_participant_fullname_pattern"
msgstr "%2$s, %1$s"

msgid "tst_participant_last_attempts"
msgstr "Letzte Versuche"

msgid "tst_participant_scored_attempts"
msgstr "Bewertete Versuche"

msgid "tst_participant_status"
msgstr "Teilnehmerstatus"

Expand Down
6 changes: 6 additions & 0 deletions components/ILIAS/Test/lang/assessment_en.po
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,12 @@ msgstr "Participant"
msgid "tst_participant_fullname_pattern"
msgstr "%2$s, %1$s"

msgid "tst_participant_last_attempts"
msgstr "Last Attempts"

msgid "tst_participant_scored_attempts"
msgstr "Scored Attempts"

msgid "tst_participant_status"
msgstr "Participant Status"

Expand Down
57 changes: 57 additions & 0 deletions components/ILIAS/Test/src/Participants/AttemptSpecifiers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\Test\Participants;

use ILIAS\Language\Language;
use ILIAS\UI\Component\ViewControl\Mode;
use ILIAS\UI\Factory as UIFactory;

enum AttemptSpecifiers: string
{
case ScoredAttempt = 'tst_participant_scored_attempts';
case LastAttempt = 'tst_participant_last_attempts';

public function getAttemptId(Participant $participant): ?int
{
return match ($this) {
self::ScoredAttempt => null,
self::LastAttempt => $participant->getLastStartedAttempt(),
};
}

public function buildViewControl(\ilCtrl $ctrl, Language $lng, UIFactory $ui_factory): Mode
{
$target_class = \ilTestParticipantsGUI::class;
$actions = [];

foreach (self::cases() as $case) {
$ctrl->setParameterByClass($target_class, 'view_mode', $case->value);
$actions[$lng->txt($case->value)] = $ctrl->getLinkTargetByClass($target_class);
}

$ctrl->clearParametersByClass($target_class);

return $ui_factory->viewControl()->mode(
$actions,
$lng->txt('participant_view_control_aria')
)->withActive($lng->txt($this->value));
}
}
46 changes: 32 additions & 14 deletions components/ILIAS/Test/src/Participants/ParticipantTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@
class ParticipantTable implements DataRetrieval
{
private const ID = 'pt';

private ?iterable $records = null;
private bool $scoring_enabled = false;
private AttemptSpecifiers $attempt_specifier;

public function __construct(
private readonly UIFactory $ui_factory,
private readonly \ilUIService $ui_service,
private readonly Language $lng,
private readonly \ilCtrl $ctrl,
private readonly \ilTestAccess $test_access,
private readonly RequestDataCollector $test_request,
private readonly \ilTestParticipantAccessFilterFactory $participant_access_filter,
Expand All @@ -57,6 +60,7 @@ public function __construct(
private readonly ParticipantTableActions $table_actions
) {
$this->scoring_enabled = $this->test_object->getGlobalSettings()->isManualScoringEnabled();
$this->attempt_specifier = AttemptSpecifiers::tryFrom($this->test_request->getViewMode()) ?? AttemptSpecifiers::LastAttempt;
}

public function execute(URLBuilder $url_builder): ?Modal
Expand Down Expand Up @@ -85,6 +89,7 @@ public function getComponents(URLBuilder $url_builder, string $filter_url): arra

return [
$summary_information,
$this->attempt_specifier->buildViewControl($this->ctrl, $this->lng, $this->ui_factory),
$filter,
$table->withActions($this->table_actions->getEnabledActions(...$this->acquireParameters($url_builder)))
];
Expand Down Expand Up @@ -479,10 +484,10 @@ private function getColumns(): array
return $columns;
}

private function loadRecords(?array $filter, Order $order): iterable
private function loadRecords(?array $filter, Order $order): void
{
if ($this->records !== null) {
return $this->records;
return;
}

$records = iterator_to_array(
Expand All @@ -493,14 +498,31 @@ private function loadRecords(?array $filter, Order $order): iterable
$order
)
);

$this->records = array_filter(
$records,
fn(Participant $participant) => in_array(
$participant->getUserId(),
$this->buildAccessFilteredParticipantsList($records)
)
$accessible_user_ids = $this->buildAccessFilteredParticipantsList($records);

$this->records = $this->results_data_factory->addAttemptOverviewInformationToParticipants(
$this->results_presentation_settings,
$this->test_object,
array_filter(
$records,
static fn(Participant $participant): bool => in_array(
$participant->getUserId(),
$accessible_user_ids,
true
)
),
$this->attempt_specifier
);
}

/**
* @return iterable<Participant>
*/
private function retrieveRecords(?array $filter, Order $order): iterable
{
if ($this->records === null) {
$this->loadRecords($filter, $order);
}

return $this->records;
}
Expand Down Expand Up @@ -532,11 +554,7 @@ private function getViewControlledRecords(?array $filter_data, Range $range, Ord
return $this->limitRecords(
$this->orderRecords(
$this->filterRecords(
$this->results_data_factory->addAttemptOverviewInformationToParticipants(
$this->results_presentation_settings,
$this->test_object,
$this->loadRecords($filter_data, $order)
),
$this->retrieveRecords($filter_data, $order),
$filter_data
),
$order
Expand Down
5 changes: 5 additions & 0 deletions components/ILIAS/Test/src/RequestDataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ public function getPassId(): int
return $this->int('pass_id');
}

public function getViewMode(): string
{
return $this->str('view_mode');
}

public function retrieveBoolFromPost(string $key): ?bool
{
if (!$this->http->wrapper()->post()->has($key)) {
Expand Down
28 changes: 15 additions & 13 deletions components/ILIAS/Test/src/Results/Data/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
namespace ILIAS\Test\Results\Data;

use ILIAS\Test\Results\Presentation\Settings as ResultPresentationSettings;
use ILIAS\Test\Participants\AttemptSpecifiers;
use ILIAS\Test\Participants\Participant;
use ILIAS\UI\Factory as UIFactory;
use ILIAS\UI\Renderer as UIRenderer;
Expand Down Expand Up @@ -130,36 +131,37 @@ public function getAttemptOverviewFor(

/**
*
* @param array<ILIAS\Test\Participants\Participant> $participants
* @return array<ILIAS\Test\Participants\Participant>
* @param array<Participant> $participants
* @return array<Participant>
*/
public function addAttemptOverviewInformationToParticipants(
ResultPresentationSettings $settings,
\ilObjTest $test_obj,
array $participants
array $participants,
AttemptSpecifiers $attempt_specifier
): array {
return array_map(
function (Participant $v) use ($settings, $test_obj, $participants): Participant {
function (Participant $v) use ($settings, $test_obj, $attempt_specifier): Participant {
if ($v->getActiveId() === null) {
return $v;
}

$scored_attempt = $this->getAttemptOverviewFor(
$attempt_overview = $this->getAttemptOverviewFor(
$settings,
$test_obj,
$v->getActiveId(),
null
$attempt_specifier->getAttemptId($v)
);

if ($scored_attempt !== null
&& $scored_attempt->getStatusOfAttempt() === StatusOfAttempt::RUNNING
&& $scored_attempt->getStartedDate() !== null) {
$v = $v->withRunningAttemptStart($scored_attempt->getStartedDate());
if (
$attempt_overview !== null
&& $attempt_overview->getStatusOfAttempt() === StatusOfAttempt::RUNNING
&& $attempt_overview->getStartedDate() !== null
) {
$v = $v->withRunningAttemptStart($attempt_overview->getStartedDate());
}

return $v->withAttemptOverviewInformation(
$scored_attempt
);
return $v->withAttemptOverviewInformation($attempt_overview);
},
$participants
);
Expand Down
Loading