diff --git a/components/ILIAS/Test/classes/class.ilObjTestGUI.php b/components/ILIAS/Test/classes/class.ilObjTestGUI.php index 1f6f63afe452..e07d0b886110 100755 --- a/components/ILIAS/Test/classes/class.ilObjTestGUI.php +++ b/components/ILIAS/Test/classes/class.ilObjTestGUI.php @@ -446,7 +446,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 693213ee7747..f06b214de20f 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 ); }, @@ -195,10 +196,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) ); @@ -341,7 +339,7 @@ public function outUserPassDetails(): void true ), $settings, - $this->buildResultsTitle($this->user->getFullname(), $pass), + $this->buildResultsTitle($active_id, $pass), false ); @@ -817,7 +815,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( @@ -828,7 +826,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.ilTestParticipantList.php b/components/ILIAS/Test/classes/class.ilTestParticipantList.php index bd61cb6c2bd5..eb73186dad59 100755 --- a/components/ILIAS/Test/classes/class.ilTestParticipantList.php +++ b/components/ILIAS/Test/classes/class.ilTestParticipantList.php @@ -252,17 +252,33 @@ public function buildScoringsQuery(): string public function getScoringTableRows(): array { $rows = []; + $participant_repository = $this->test_obj->getLocalDIC()['participant.repository']; foreach ($this as $participant) { - $row = [ + $firstname = $participant->getFirstname(); + $lastname = $participant->getLastname(); + + if ($participant->getUsrId() === ANONYMOUS_USER_ID) { + $name = explode( + ',', + $participant_repository->getParticipantByActiveId( + $this->test_obj->getTestId(), + $participant->getActiveId() + )->getDisplayName($this->lng) + ); + if (isset($name[0], $name[1])) { + $firstname = explode(' ', trim($name[1]))[0] ?? ''; + $lastname = explode(' ', trim($name[0]))[0] ?? ''; + } + } + + $rows[] = [ 'usr_id' => $participant->getUsrId(), 'active_id' => $participant->getActiveId(), 'login' => $participant->getLogin(), - 'firstname' => $participant->getFirstname(), - 'lastname' => $participant->getLastname() + 'firstname' => $firstname, + 'lastname' => $lastname ]; - - $rows[] = $row; } return $rows; diff --git a/components/ILIAS/Test/classes/class.ilTestResultsGUI.php b/components/ILIAS/Test/classes/class.ilTestResultsGUI.php index cea9b8df6fd5..a691d6e8cd2f 100755 --- a/components/ILIAS/Test/classes/class.ilTestResultsGUI.php +++ b/components/ILIAS/Test/classes/class.ilTestResultsGUI.php @@ -18,10 +18,10 @@ declare(strict_types=1); +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\RequestDataCollector; use ILIAS\Test\Presentation\TabsManager; use ILIAS\Test\Logging\TestLogger; -use ILIAS\Test\Settings\ScoreReporting\SettingsResultSummary; use ILIAS\Test\Settings\ScoreReporting\ScoreReportingTypes; use ILIAS\TestQuestionPool\Questions\GeneralQuestionPropertiesRepository; use ILIAS\Test\Results\Toplist\TestTopListRepository; @@ -73,7 +73,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 +154,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 2a45f0f4b16c..5ebc9e6309e5 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($title, $table->getColumns(), $table) diff --git a/components/ILIAS/Test/src/Participants/ParticipantRepository.php b/components/ILIAS/Test/src/Participants/ParticipantRepository.php index 9a2a56b1a700..7f6e27e8072d 100755 --- a/components/ILIAS/Test/src/Participants/ParticipantRepository.php +++ b/components/ILIAS/Test/src/Participants/ParticipantRepository.php @@ -356,6 +356,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, @@ -394,6 +395,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/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 513954455e56..89c78dbbd397 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 ) { } @@ -152,7 +154,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 1ed3e2dae556..568a93edf714 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/ScoringByQuestionTableBinder.php b/components/ILIAS/Test/src/Scoring/Manual/ScoringByQuestionTableBinder.php index d4ff3f0a1615..684b6e4d1fb1 100644 --- a/components/ILIAS/Test/src/Scoring/Manual/ScoringByQuestionTableBinder.php +++ b/components/ILIAS/Test/src/Scoring/Manual/ScoringByQuestionTableBinder.php @@ -20,6 +20,7 @@ namespace ILIAS\Test\Scoring\Manual; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\UI\Component\Table\DataRetrieval; use ILIAS\UI\Component\Table\DataRowBuilder; use ILIAS\Data\Range; @@ -36,6 +37,7 @@ public function __construct( private readonly \DateTimeZone $timezone, private readonly \ilTestParticipantAccessFilterFactory $participant_access_filter_factory, private readonly \ilObjTest $test_obj, + private readonly ParticipantRepository $participant_repository, private readonly int $question_id ) { } @@ -169,7 +171,7 @@ function ( $row = [ "{$active_id}_{$pd->getPass()}", - ScoringByQuestionTable::COLUMN_NAME => $this->buildParticipantName($current_participant), + ScoringByQuestionTable::COLUMN_NAME => $this->buildParticipantName($current_participant, $active_id), ScoringByQuestionTable::COLUMN_ATTEMPT => $pd->getPass() + 1, ScoringByQuestionTable::COLUMN_POINTS_REACHED => $current_pass->getStatusOfAttempt()->isFinished() ? ($question_result['reached'] ?? 0.0) : 0.0, ScoringByQuestionTable::COLUMN_POINTS_AVAILABLE => $current_participant->getQuestionByAttemptAndId($pd->getPass(), $question_id)['points'] ?? 0.0, @@ -236,12 +238,13 @@ static function (array $c, \ilTestEvaluationUserData $v): array { ); } - private function buildParticipantName(\ilTestEvaluationUserData $participant_data): string + private function buildParticipantName(\ilTestEvaluationUserData $participant_data, int $active_id): string { - if ($this->test_obj->getAnonymity()) { - return $this->lng->txt('anonymous'); - } - return $participant_data->getName(); + $participant = $this->participant_repository->getParticipantByActiveId($this->test_obj->getTestId(), $active_id); + $importname = $participant->getImportname(); + return $participant->getUserId() === ANONYMOUS_USER_ID && $importname !== null && $importname !== '' + ? $participant->getDisplayName($this->lng) + : $participant_data->getName(); } private function buildFinalizedByName(array $feedback_data): string diff --git a/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByParticipantGUI.php b/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByParticipantGUI.php index d8c222714697..961c69a856b8 100755 --- a/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByParticipantGUI.php +++ b/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByParticipantGUI.php @@ -20,6 +20,7 @@ namespace ILIAS\Test\Scoring\Manual; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\Presentation\TabsManager; use ILIAS\Test\Logging\TestScoringInteractionTypes; use ILIAS\Test\Logging\AdditionalInformationGenerator; @@ -40,10 +41,12 @@ class TestScoringByParticipantGUI extends \ilTestServiceGUI public const PART_FILTER_MANSCORING_NONE = 5; protected \ilTestAccess $test_access; + protected ParticipantRepository $participant_repository; public function __construct(\ilObjTest $object) { parent::__construct($object); + $this->participant_repository = $object->getLocalDIC()['participant.repository']; } /** @@ -181,10 +184,10 @@ private function showManScoringParticipantScreen(\ilPropertyFormGUI $form = null $table = new TestScoringByParticipantPassesOverviewTableGUI($this, 'showManScoringParticipantScreen'); - $user_id = $this->object->_getUserIdFromActiveId($active_id); - $user_fullname = $this->object->userLookupFullName($user_id, false, true); - $table_title = sprintf($this->lng->txt('tst_pass_overview_for_participant'), $user_fullname); - $table->setTitle($table_title); + $participant = $this->participant_repository->getParticipantByActiveId($this->object->getTestId(), $active_id); + $table->setTitle( + sprintf($this->lng->txt('tst_pass_overview_for_participant'), $participant->getDisplayName($this->lng)) + ); $passOverviewData = $this->service->getPassOverviewData($active_id); $table->setData($passOverviewData['passes']); diff --git a/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByQuestionGUI.php b/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByQuestionGUI.php index abfceafbc3c1..df6f95e0ca5e 100755 --- a/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByQuestionGUI.php +++ b/components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByQuestionGUI.php @@ -20,6 +20,7 @@ namespace ILIAS\Test\Scoring\Manual; +use ILIAS\Test\Participants\ParticipantRepository; use ILIAS\Test\Presentation\TabsManager; use ILIAS\Test\Logging\TestScoringInteractionTypes; use ILIAS\Test\Logging\AdditionalInformationGenerator; @@ -141,6 +142,7 @@ protected function showManScoringByQuestionParticipantsTable( new \DateTimeZone($this->user->getTimeZone()), $this->participant_access_filter, $this->object, + $this->participant_repository, $question_id ) ) @@ -389,12 +391,8 @@ private function buildAutosavedSolutionPanel( private function getModalTitle(int $active_id): string { - if ($this->object->getAnonymity() === true) { - return $this->lng->txt('answers_of') . ' ' . $this->lng->txt('anonymous'); - } - - $participant = $this->object->getCompleteEvaluationData()->getParticipant($active_id); - return "{$this->lng->txt('answers_of')} {$participant->getName()} ({$participant->getLogin()})"; + $participant = $this->participant_repository->getParticipantByActiveId($this->object->getTestId(), $active_id); + return "{$this->lng->txt('answers_of')} {$participant->getDisplayName($this->lng, $this->object->getAnonymity())}"; } private function buildForm( diff --git a/components/ILIAS/Test/tests/Scoring/Toplist/DataRetrievalTest.php b/components/ILIAS/Test/tests/Scoring/Toplist/DataRetrievalTest.php index 677c474cd671..e62c1911becb 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/ilTestBaseTestCaseTrait.php b/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php index 82f956c96ea8..98fee120c2e3 100644 --- a/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php +++ b/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php @@ -379,6 +379,10 @@ protected function buildLocalDICMock(): ILIAS\Test\TestDIC => $this->createMock( \ILIAS\Test\RequestDataCollector::class ); + $local_dic_mock['participant.repository'] = fn(Pimple\Container $c) + => $this->createMock( + \ILIAS\Test\Participants\ParticipantRepository::class + ); $local_dic_mock['participant.access_filter.factory'] = fn(Pimple\Container $c) => $this->createMock( \ilTestParticipantAccessFilterFactory::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) ); }