diff --git a/components/ILIAS/Test/classes/class.ilObjTestGUI.php b/components/ILIAS/Test/classes/class.ilObjTestGUI.php index 07b0e0f626f3..cc13699f4b1a 100755 --- a/components/ILIAS/Test/classes/class.ilObjTestGUI.php +++ b/components/ILIAS/Test/classes/class.ilObjTestGUI.php @@ -481,7 +481,8 @@ public function executeCommand(): void $this->http, $this->data_factory, $this->test_session_factory->getSession(), - $this->getObjectiveOrientedContainer() + $this->getObjectiveOrientedContainer(), + $this->participant_repository ); $this->ctrl->forwardCommand($gui); diff --git a/components/ILIAS/Test/classes/class.ilTestEvaluationGUI.php b/components/ILIAS/Test/classes/class.ilTestEvaluationGUI.php index fe52933b650e..4b130cf7cb61 100755 --- a/components/ILIAS/Test/classes/class.ilTestEvaluationGUI.php +++ b/components/ILIAS/Test/classes/class.ilTestEvaluationGUI.php @@ -18,8 +18,10 @@ declare(strict_types=1); +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\Results\Presentation\TitlesBuilder as ResultsTitlesBuilder; use ILIAS\Test\Presentation\PrintLayoutProvider; +use ILIAS\Test\TestDIC; use ILIAS\UI\Component\ViewControl\Mode as ViewControlMode; use ILIAS\UI\Component\Link\Standard as StandardLink; use ILIAS\UI\Component\Panel\Sub as SubPanel; @@ -48,11 +50,13 @@ class ilTestEvaluationGUI extends ilTestServiceGUI private const DEFAULT_CMD = 'outUserListOfAnswerPasses'; protected ilTestAccess $testAccess; protected ilTestProcessLockerFactory $processLockerFactory; + private readonly ParticipantRepository $participant_repository; public function __construct(ilObjTest $object) { parent::__construct($object); $this->participant_access_filter = new ilTestParticipantAccessFilterFactory($this->access); + $this->participant_repository = TestDIC::dic()['participant.repository']; $this->processLockerFactory = new ilTestProcessLockerFactory( new ilSetting('assessment'), @@ -138,10 +142,7 @@ function (string $v): SubPanel { $attempt_id = ilObjTest::_getResultPass($value); $components = $this->buildAttemptComponents($value, $attempt_id, false, true); return $this->ui_factory->panel()->sub( - $this->buildResultsTitle( - ilObjUser::_lookupFullname($this->object->_getUserIdFromActiveId($value)), - $attempt_id - ), + $this->buildResultsTitle($value, $attempt_id), $components ); }, @@ -183,10 +184,7 @@ public function showResults(): void } $results_panel = $this->ui_factory->panel()->report( - $this->buildResultsTitle( - ilObjUser::_lookupFullname($this->object->_getUserIdFromActiveId($current_active_id)), - $attempt_id - ), + $this->buildResultsTitle($current_active_id, $attempt_id), $this->buildAttemptComponents($current_active_id, $attempt_id, true, false) ); @@ -327,7 +325,7 @@ public function outUserPassDetails(): void true ), $settings, - $this->buildResultsTitle($this->user->getFullname(), $pass), + $this->buildResultsTitle($active_id, $pass), false ); @@ -783,7 +781,7 @@ protected function sendPage(string $page) $this->http->close(); } - protected function buildResultsTitle(string $fullname, int $pass): string + protected function buildResultsTitle(int $active_id, int $pass): string { if ($this->object->getAnonymity()) { return sprintf( @@ -794,7 +792,7 @@ protected function buildResultsTitle(string $fullname, int $pass): string return sprintf( $this->lng->txt('tst_result_user_name_pass'), $pass + 1, - $fullname + $this->participant_repository->getParticipantByActiveId($this->object->getTestId(), $active_id)->getDisplayName($this->lng) ); } diff --git a/components/ILIAS/Test/classes/class.ilTestResultsGUI.php b/components/ILIAS/Test/classes/class.ilTestResultsGUI.php index cea9b8df6fd5..da42dde929e6 100755 --- a/components/ILIAS/Test/classes/class.ilTestResultsGUI.php +++ b/components/ILIAS/Test/classes/class.ilTestResultsGUI.php @@ -18,6 +18,7 @@ declare(strict_types=1); +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\RequestDataCollector; use ILIAS\Test\Presentation\TabsManager; use ILIAS\Test\Logging\TestLogger; @@ -73,7 +74,8 @@ public function __construct( private readonly GlobalHttpState $http, private readonly DataFactory $data_factory, private readonly ilTestSession $test_session, - private readonly ilTestObjectiveOrientedContainer $objective_parent + private readonly ilTestObjectiveOrientedContainer $objective_parent, + private readonly ParticipantRepository $participant_repository ) { } @@ -153,7 +155,8 @@ public function executeCommand(): void $this->ui_factory, $this->ui_renderer, $this->data_factory, - $this->http + $this->http, + $this->participant_repository ); $this->ctrl->forwardCommand($gui); break; diff --git a/components/ILIAS/Test/classes/class.ilTestToplistGUI.php b/components/ILIAS/Test/classes/class.ilTestToplistGUI.php index 2f693af25d94..dc88db411720 100755 --- a/components/ILIAS/Test/classes/class.ilTestToplistGUI.php +++ b/components/ILIAS/Test/classes/class.ilTestToplistGUI.php @@ -18,6 +18,7 @@ declare(strict_types=1); +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\Results\Toplist\TestTopListRepository; use ILIAS\Test\Results\Toplist\DataRetrieval; use ILIAS\Test\Results\Toplist\TopListOrder; @@ -45,7 +46,8 @@ public function __construct( protected readonly UIFactory $ui_factory, protected readonly UIRenderer $ui_renderer, protected readonly DataFactory $data_factory, - protected readonly GlobalHttpState $http_state + protected readonly GlobalHttpState $http_state, + protected readonly ParticipantRepository $participant_repository ) { } @@ -133,7 +135,8 @@ protected function buildTable(string $title, TopListType $list_type, TopListOrde $this->ui_renderer, $this->data_factory, $list_type, - $order_by + $order_by, + $this->participant_repository ); return $this->ui_factory->table() ->data($table, $title, $table->getColumns()) diff --git a/components/ILIAS/Test/src/GUIFactory.php b/components/ILIAS/Test/src/GUIFactory.php index 264b3ff630c4..49fc2e305a33 100644 --- a/components/ILIAS/Test/src/GUIFactory.php +++ b/components/ILIAS/Test/src/GUIFactory.php @@ -77,6 +77,8 @@ public function __construct( $this->test_dic['scoring.manual.done_helper'], $this->global_dic['ilUser'], $this->internal['test.access']($test_obj), + $this->test_dic['participant.repository'], + $this->global_dic['lng'], ); $this->internal['manscoring.positionsfactory'] = fn(\ilObjTest $test_obj): PositionsFactory => diff --git a/components/ILIAS/Test/src/Participants/Participant.php b/components/ILIAS/Test/src/Participants/Participant.php index 279577d0f573..4d0c0bcd719a 100644 --- a/components/ILIAS/Test/src/Participants/Participant.php +++ b/components/ILIAS/Test/src/Participants/Participant.php @@ -20,6 +20,7 @@ namespace ILIAS\Test\Participants; +use ILIAS\Language\Language; use ILIAS\Test\Results\Data\AttemptOverview; class Participant @@ -35,6 +36,7 @@ public function __construct( private readonly string $firstname = '', private readonly string $lastname = '', private readonly string $login = '', + private readonly ?string $importname = null, private readonly string $matriculation = '', private int $extra_time = 0, private readonly int $attempts = 0, @@ -86,6 +88,11 @@ public function getLogin(): string return $this->login; } + public function getImportname(): ?string + { + return $this->importname; + } + public function getMatriculation(): string { return $this->matriculation; @@ -235,4 +242,20 @@ public function isScoringFinalized(): bool { return $this->scoring_finalized; } + + public function getDisplayName(Language $language): string + { + $display_name = ''; + + if ($this->firstname) { + $display_name .= $this->firstname . ' '; + } + if ($this->lastname) { + $display_name .= $this->lastname; + } + + return $this->user_id === ANONYMOUS_USER_ID && $this->importname !== null && $this->importname !== '' + ? "{$this->importname} ({$language->txt('imported')})" + : $display_name; + } } diff --git a/components/ILIAS/Test/src/Participants/ParticipantRepository.php b/components/ILIAS/Test/src/Participants/ParticipantRepository.php index 2e0559822ca7..553b99256877 100755 --- a/components/ILIAS/Test/src/Participants/ParticipantRepository.php +++ b/components/ILIAS/Test/src/Participants/ParticipantRepository.php @@ -329,6 +329,7 @@ private function arrayToObject(array $row): Participant $row['firstname'] ?? '', $row['lastname'] ?? '', $row['login'] ?? '', + $row['importname'] ?? null, $row['matriculation'] ?? '', $row['extra_time'] ?? 0, $row['tries'] ?? 0, @@ -357,6 +358,7 @@ private function getActiveParticipantsQuery(): string ta.anonymous_id, ta.tries, ta.submitted, + ta.importname, ta.last_finished_pass, ta.last_started_pass, COALESCE(ta.last_started_pass, -1) <> COALESCE(ta.last_finished_pass, -1) as unfinished_attempts, @@ -395,6 +397,7 @@ private function getInvitedParticipantsQuery(): string ta.anonymous_id, ta.tries, ta.submitted, + ta.importname, ta.last_finished_pass, ta.last_started_pass, COALESCE(ta.last_started_pass, -1) <> COALESCE(ta.last_finished_pass, -1) as unfinished_attempts, diff --git a/components/ILIAS/Test/src/Participants/ParticipantTable.php b/components/ILIAS/Test/src/Participants/ParticipantTable.php index ff5ab5e4a9de..b017d2c52f9b 100644 --- a/components/ILIAS/Test/src/Participants/ParticipantTable.php +++ b/components/ILIAS/Test/src/Participants/ParticipantTable.php @@ -108,7 +108,7 @@ public function getRows( $total_duration = $record->getTotalDuration($processing_time); $status_of_attempt = $record->getAttemptOverviewInformation()?->getStatusOfAttempt() ?? StatusOfAttempt::NOT_YET_STARTED; $row = [ - 'name' => $this->test_object->buildName($record->getUserId(), $record->getFirstname(), $record->getLastname()), + 'name' => $record->getDisplayName($this->lng), 'login' => $record->getLogin(), 'matriculation' => $record->getMatriculation(), 'total_time_on_task' => $record->getAttemptOverviewInformation()?->getHumanReadableTotalTimeOnTask() ?? '', diff --git a/components/ILIAS/Test/src/Participants/ParticipantTableDeleteResultsAction.php b/components/ILIAS/Test/src/Participants/ParticipantTableDeleteResultsAction.php index 808331505d00..22ddff5b9323 100644 --- a/components/ILIAS/Test/src/Participants/ParticipantTableDeleteResultsAction.php +++ b/components/ILIAS/Test/src/Participants/ParticipantTableDeleteResultsAction.php @@ -84,7 +84,7 @@ public function getModal( (string) $v->getUserId(), $this->test_obj->getAnonymity() ? $this->lng->txt('anonymous') - : \ilObjUser::_lookupFullname($v->getUserId()) + : $v->getDisplayName($this->lng) ), $selected_participants ) diff --git a/components/ILIAS/Test/src/Results/Toplist/DataRetrieval.php b/components/ILIAS/Test/src/Results/Toplist/DataRetrieval.php index e6fe5a4b62de..b5352356105d 100755 --- a/components/ILIAS/Test/src/Results/Toplist/DataRetrieval.php +++ b/components/ILIAS/Test/src/Results/Toplist/DataRetrieval.php @@ -23,6 +23,7 @@ use ILIAS\Data\Factory as DataFactory; use ILIAS\Data\Range; use ILIAS\Data\Order; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\UI\Component\Symbol\Icon\Standard as Icon; use ILIAS\UI\Component\Table\DataRowBuilder; use ILIAS\UI\Factory as UIFactory; @@ -39,7 +40,8 @@ public function __construct( protected readonly UIRenderer $ui_renderer, protected readonly DataFactory $data_factory, protected readonly TopListType $list_type, - protected readonly TopListOrder $order_by + protected readonly TopListOrder $order_by, + protected readonly ParticipantRepository $participant_repository ) { } @@ -151,7 +153,7 @@ private function buildBasicItemFromRowArray(array $row): array 'rank' => "{$row['rank']}.", 'participant' => $this->test_obj->isHighscoreAnon() && (int) $row['usr_id'] !== $this->user->getId() ? '-, -' - : $row['lastname'] . ', ' . $row['firstname'], + : $this->participant_repository->getParticipantByActiveId($this->test_obj->getTestId(), $row['active_id'])->getDisplayName($this->lng), 'is_actor' => isset($row['usr_id']) && ((int) $row['usr_id'] === $this->user->getId()) ]; } diff --git a/components/ILIAS/Test/src/Results/Toplist/TestTopListRepository.php b/components/ILIAS/Test/src/Results/Toplist/TestTopListRepository.php index 56f350fb44d1..bc3d88bb19e5 100755 --- a/components/ILIAS/Test/src/Results/Toplist/TestTopListRepository.php +++ b/components/ILIAS/Test/src/Results/Toplist/TestTopListRepository.php @@ -32,7 +32,7 @@ public function getGeneralToplist(\ilObjTest $object, TopListOrder $order_by): \ $this->db->setLimit($object->getHighscoreTopNum(), 0); $result = $this->db->query( ' - 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 + 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, tst_active.active_id FROM object_reference INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi @@ -107,7 +107,7 @@ public function getUserToplistByPercentage(\ilObjTest $object, int $a_user_id): $result = $this->db->query(" SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage , - tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname + tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname, tst_active.active_id FROM object_reference INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi @@ -192,7 +192,7 @@ public function getUserToplistByWorkingtime(\ilObjTest $object, int $a_user_id): $result = $this->db->query(" SELECT tst_result_cache.*, round(reached_points/max_points*100) as percentage, - tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname + tst_pass_result.workingtime, usr_id, usr_data.firstname, usr_data.lastname, tst_active.active_id FROM object_reference INNER JOIN tst_tests ON object_reference.obj_id = tst_tests.obj_fi INNER JOIN tst_active ON tst_tests.test_id = tst_active.test_fi diff --git a/components/ILIAS/Test/src/Scoring/Manual/ConsecutiveScoring.php b/components/ILIAS/Test/src/Scoring/Manual/ConsecutiveScoring.php index ab620edd67ac..3bac8f205a12 100644 --- a/components/ILIAS/Test/src/Scoring/Manual/ConsecutiveScoring.php +++ b/components/ILIAS/Test/src/Scoring/Manual/ConsecutiveScoring.php @@ -20,10 +20,11 @@ namespace ILIAS\Test\Scoring\Manual; -use ILIAS\TestQuestionPool\Questions\GeneralQuestionPropertiesRepository; +use ILIAS\Language\Language; use ILIAS\Test\Logging\TestLogger; use ILIAS\Test\Logging\TestScoringInteractionTypes; use ILIAS\Test\Logging\AdditionalInformationGenerator; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\TestManScoringDoneHelper; class ConsecutiveScoring @@ -37,6 +38,8 @@ public function __construct( private TestManScoringDoneHelper $scoring_done_helper, private \ilObjUser $current_user, private readonly \ilTestAccess $test_access, + private readonly ParticipantRepository $participant_repository, + private readonly Language $lng, ) { } @@ -94,9 +97,16 @@ public function getUserFullName( ) { return \ilObjTest::buildExamId($usr_active_id, $attempt, $this->object->getId()); } - $user_id = (string) $this->object->_getUserIdFromActiveId($usr_active_id); - $user_data = $this->object->getUserData([$user_id]); - $user = $user_data[$user_id]; + + $participant = $this->participant_repository->getParticipantByActiveId($this->object->getTestId(), $usr_active_id); + $importname = $participant->getImportname(); + $user_id = $participant->getUserId(); + if ($user_id === ANONYMOUS_USER_ID && $importname !== null && $importname !== '') { + return $participant->getDisplayName($this->lng); + } + + $user_id = (string) $user_id; + $user = $this->object->getUserData([$user_id])[$user_id]; return sprintf( "%s %s [%s]", $user["firstname"], diff --git a/components/ILIAS/Test/tests/Scoring/Toplist/DataRetrievalTest.php b/components/ILIAS/Test/tests/Scoring/Toplist/DataRetrievalTest.php index 53877410f407..aa5cde018e52 100755 --- a/components/ILIAS/Test/tests/Scoring/Toplist/DataRetrievalTest.php +++ b/components/ILIAS/Test/tests/Scoring/Toplist/DataRetrievalTest.php @@ -21,6 +21,7 @@ namespace Results\Toplist; use ILIAS\Data\Factory; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\Results\Toplist\TestTopListRepository; use ILIAS\Test\Results\Toplist\DataRetrieval; use ILIAS\Test\Results\Toplist\TopListOrder; @@ -56,7 +57,8 @@ protected function setUp(): void $DIC['ui.renderer'], $this->createMock(Factory::class), TopListType::GENERAL, - TopListOrder::BY_SCORE + TopListOrder::BY_SCORE, + $this->createMock(ParticipantRepository::class) ); } diff --git a/components/ILIAS/Test/tests/ilTestResultsGUITest.php b/components/ILIAS/Test/tests/ilTestResultsGUITest.php index 85b3e0138c36..efc51d394c95 100755 --- a/components/ILIAS/Test/tests/ilTestResultsGUITest.php +++ b/components/ILIAS/Test/tests/ilTestResultsGUITest.php @@ -18,6 +18,8 @@ declare(strict_types=1); +use ILIAS\Test\Participants\ParticipantRepository; + /** * Class ilTestResultsGUITest * @author Marvin Beym @@ -56,7 +58,8 @@ protected function setUp(): void $DIC['http'], $this->createMock(ILIAS\Data\Factory::class), $this->createMock(ilTestSession::class), - $this->createMock(ilTestObjectiveOrientedContainer::class) + $this->createMock(ilTestObjectiveOrientedContainer::class), + $this->createMock(ParticipantRepository::class) ); } diff --git a/components/ILIAS/Test/tests/ilTestToplistGUITest.php b/components/ILIAS/Test/tests/ilTestToplistGUITest.php index 1b1fcfab7098..1778d6f4ba15 100755 --- a/components/ILIAS/Test/tests/ilTestToplistGUITest.php +++ b/components/ILIAS/Test/tests/ilTestToplistGUITest.php @@ -19,6 +19,7 @@ declare(strict_types=1); use ILIAS\Data\Factory; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\Results\Toplist\TestTopListRepository; /** @@ -44,7 +45,8 @@ protected function setUp(): void $DIC['ui.factory'], $DIC['ui.renderer'], $this->createMock(Factory::class), - $DIC['http'] + $DIC['http'], + $this->createMock(ParticipantRepository::class) ); }