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 @@ -181,6 +181,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
52 changes: 45 additions & 7 deletions components/ILIAS/Test/src/Participants/ParticipantTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,26 @@
use ILIAS\UI\Component\Input\Field\Factory as FieldFactory;
use ILIAS\UI\Component\Table\DataRetrieval;
use ILIAS\UI\Component\Table\DataRowBuilder;
use ILIAS\UI\Component\ViewControl\Mode;
use ILIAS\UI\Factory as UIFactory;
use ILIAS\UI\URLBuilder;
use Psr\Http\Message\ServerRequestInterface;

class ParticipantTable implements DataRetrieval
{
private const ID = 'pt';
public const VIEW_MODE_PARAMETER = 'view_mode';
public const VIEW_MODE_SCORED_ATTEMPTS = 'scored_attempts';
public const VIEW_MODE_LAST_ATTEMPTS = 'last_attempts';

private ?iterable $records = null;
private string $view_mode;

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 @@ -55,6 +62,10 @@ public function __construct(
private readonly \ilObjTest $test_object,
private readonly ParticipantTableActions $table_actions
) {
$view_mode = $this->test_request->getViewMode();
$this->view_mode = in_array($view_mode, [self::VIEW_MODE_SCORED_ATTEMPTS, self::VIEW_MODE_LAST_ATTEMPTS])
? $view_mode
: self::VIEW_MODE_LAST_ATTEMPTS;
}

public function execute(URLBuilder $url_builder): ?Modal
Expand All @@ -74,11 +85,37 @@ public function getComponents(URLBuilder $url_builder, string $filter_url): arra
);

return [
$this->getModeViewControlComponent(),
$filter,
$table->withActions($this->table_actions->getEnabledActions(...$this->acquireParameters($url_builder)))
];
}

private function getModeViewControlComponent(): Mode
{
$target_class = \ilTestParticipantsGUI::class;
$this->ctrl->setParameterByClass($target_class, self::VIEW_MODE_PARAMETER, 'scored_attempts');
$scored_attempts_target = $this->ctrl->getLinkTargetByClass($target_class);
$this->ctrl->setParameterByClass($target_class, self::VIEW_MODE_PARAMETER, 'last_attempts');
$last_attempts_target = $this->ctrl->getLinkTargetByClass($target_class);
$this->ctrl->clearParametersByClass($target_class);

$scored_attempts_label = $this->lng->txt('tst_participant_scored_attempts');
$last_attempts_label = $this->lng->txt('tst_participant_last_attempts');

return $this->ui_factory->viewControl()->mode(
[
$scored_attempts_label => $scored_attempts_target,
$last_attempts_label => $last_attempts_target
],
$this->lng->txt('participant_view_control_aria')
)->withActive(
$this->view_mode === self::VIEW_MODE_LAST_ATTEMPTS
? $last_attempts_label
: $scored_attempts_label
);
}

public function getTotalRowCount(?array $filter_data, ?array $additional_parameters): ?int
{
return $this->repository->countParticipants($this->test_object->getTestId(), $filter_data);
Expand Down Expand Up @@ -442,15 +479,20 @@ private function loadRecords(?array $filter, Order $order): iterable
)
);

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

return $this->records;
return $this->records = $this->results_data_factory->addAttemptOverviewInformationToParticipants(
$this->results_presentation_settings,
$this->test_object,
$records,
$this->view_mode === self::VIEW_MODE_LAST_ATTEMPTS
);
}

/**
Expand Down Expand Up @@ -480,11 +522,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->loadRecords($filter_data, $order),
$filter_data
),
$order
Expand Down
7 changes: 5 additions & 2 deletions components/ILIAS/Test/src/RequestDataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
use ILIAS\Repository\BaseGUIRequest;
use Psr\Http\Message\ServerRequestInterface;

use function array_map;

class RequestDataCollector
{
use BaseGUIRequest;
Expand Down Expand Up @@ -97,6 +95,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
7 changes: 4 additions & 3 deletions components/ILIAS/Test/src/Results/Data/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,11 @@ public function getAttemptOverviewFor(
public function addAttemptOverviewInformationToParticipants(
ResultPresentationSettings $settings,
\ilObjTest $test_obj,
array $participants
array $participants,
bool $last_attempt = false
): array {
return array_map(
function (Participant $v) use ($settings, $test_obj, $participants): Participant {
function (Participant $v) use ($settings, $test_obj, $last_attempt): Participant {
if ($v->getActiveId() === null) {
return $v;
}
Expand All @@ -149,7 +150,7 @@ function (Participant $v) use ($settings, $test_obj, $participants): Participant
$settings,
$test_obj,
$v->getActiveId(),
null
$last_attempt ? $v->getLastStartedAttempt() : null
);

if ($scored_attempt !== null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ function (
array $c,
\ilTestEvaluationPassData $pd
) use ($question_id, $active_id, $filtered_participants, $complete_feedback): array {
if (!$pd->getStatusOfAttempt()->isFinished()) {
return $c;
}

$question_result = $pd->getAnsweredQuestionByQuestionId($question_id);
$feedback_data = $complete_feedback[$active_id][$pd->getPass()][$question_id] ?? [];
if ($this->isFilteredAttempt($pd, $question_result, $feedback_data)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,14 @@ protected function showManScoringByQuestionParticipantsTable(

if ($this->testrequest->strVal($this->action_parameter_token->getName()) === ScoringByQuestionTable::ACTION_SCORING) {
$affected_rows = $this->testrequest->raw($this->row_id_token->getName());
$this->getAnswerDetail($question_id, $affected_rows[0]);
[$active_id, $attempt] = explode('_', $affected_rows[0]);

if ($this->isAttemptFinished((int) $active_id, (int) $attempt)) {
$this->getAnswerDetail($question_id, $affected_rows[0]);
return;
}

$this->http->close();
}

$content = [
Expand Down Expand Up @@ -158,8 +165,12 @@ protected function saveManScoringByQuestion(): void
$active_id = $this->testrequest->getActiveId();
$question_id = $this->testrequest->getQuestionId();
$attempt = $this->testrequest->getPassId();
if ($active_id === 0 || $question_id === 0
|| !$this->test_access->checkScoreParticipantsAccessForActiveId($active_id, $this->object->getTestId())) {
if (
$active_id === 0
|| $question_id === 0
|| !$this->test_access->checkScoreParticipantsAccessForActiveId($active_id, $this->object->getTestId())
|| !$this->isAttemptFinished($active_id, $attempt)
) {
$this->tpl->setOnScreenMessage('info', $this->lng->txt('cannot_edit_test'), true);
$this->ctrl->redirectByClass(\ilObjTestGUI::class);
}
Expand Down Expand Up @@ -270,7 +281,10 @@ protected function getAnswerDetail(int $question_id, string $row_id): void
$this->refinery->kindlyTo()->int()
)->transform($row_info_array);

if (!$this->getTestAccess()->checkScoreParticipantsAccessForActiveId($active_id, $this->object->getTestId())) {
if (
!$this->getTestAccess()->checkScoreParticipantsAccessForActiveId($active_id, $this->object->getTestId())
|| !$this->isAttemptFinished($active_id, $attempt)
) {
$this->http->close();
}

Expand Down Expand Up @@ -488,6 +502,16 @@ function (TestQuestionProperties $v): StandardLink {
return $dropdown;
}

private function isAttemptFinished(int $active_id, int $attempt): bool
{
$pass_data = $this->object
->getCompleteEvaluationData()
->getParticipant($active_id)
?->getPass($attempt);

return $pass_data !== null && $pass_data->getStatusOfAttempt()->isFinished();
}

private function buildQuestionTitleWithPoints(TestQuestionProperties $test_question_properties): string
{
$question_properties = $test_question_properties->getGeneralQuestionProperties();
Expand Down
2 changes: 2 additions & 0 deletions lang/ilias_de.lang
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,8 @@ assessment#:#tst_optional_questions_confirmation_non_fixed_test#:#<b>Fragen zu b
assessment#:#tst_out_of_time_message#:#Sie haben die maximal erlaubte Bearbeitungszeit des Tests erreicht!
assessment#:#tst_participant#:#Teilnehmer
assessment#:#tst_participant_fullname_pattern#:#%2$s, %1$s
assessment#:#tst_participant_last_attempts#:#Letzte Versuche
assessment#:#tst_participant_scored_attempts#:#Bewertete Versuche
assessment#:#tst_participant_status#:#Teilnehmerstatus
assessment#:#tst_participating_users#:#Teilnehmende Benutzer
assessment#:#tst_pass_best_pass#:#Besten Durchlauf des Tests bewerten
Expand Down
2 changes: 2 additions & 0 deletions lang/ilias_en.lang
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,8 @@ assessment#:#tst_optional_questions_confirmation_non_fixed_test#:#<b>Question re
assessment#:#tst_out_of_time_message#:#You have reached the maximum allowed processing time of the test!
assessment#:#tst_participant#:#Participant
assessment#:#tst_participant_fullname_pattern#:#%2$s, %1$s
assessment#:#tst_participant_last_attempts#:#Last Attempts
assessment#:#tst_participant_scored_attempts#:#Scored Attempts
assessment#:#tst_participant_status#:#Participant Status
assessment#:#tst_participating_users#:#Participating Users
assessment#:#tst_pass_best_pass#:#Score the Best Attempt
Expand Down
Loading