19 declare(strict_types=1);
    65         private readonly ContentStyle $content_style,
    73         $this->ref_id = $this->
object->getRefId();
    74         $this->main_settings = $this->
object->getMainSettings();
    77         $this->test_session = (new \ilTestSessionFactory($this->
object, $this->database, $this->
user))->getSession();
    79         $this->test_passes_selector = new \ilTestPassesSelector($this->database, $this->
object);
    80         $this->test_passes_selector->setActiveId($this->test_session->getActiveId());
    81         $this->test_passes_selector->setLastFinishedPass($this->test_session->getLastFinishedPass());
    82         $this->password_checker = new \ilTestPasswordChecker($this->rbac_system, $this->
user, $this->
object, $this->
lng);
    87         if ($this->
access->checkAccess(
'read', 
'', $this->ref_id)) {
    88             $this->{$this->
ctrl->getCmd(self::DEFAULT_CMD)}();
    94         if (!$this->
object->getMainSettings()->getAdditionalSettings()->getHideInfoTab()) {
    95             $this->
ctrl->redirectByClass([\ilRepositoryGUI::class, \ilObjTestGUI::class, \ilInfoScreenGUI::class]);
    98         $this->tpl->setOnScreenMessage(
'failure', sprintf(
    99             $this->
lng->txt(
'msg_no_perm_read_item'),
   100             $this->
object->getTitle()
   103         $this->
ctrl->redirectByClass(\ilRepositoryGUI::class);
   119         $this->tpl->setContent(
   120             $this->ui_renderer->render(
   128         $message_box_message = 
'';
   129         $message_box_message_elements = [];
   131         $exam_conditions_enabled = $this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled();
   132         $password_enabled = $this->main_settings->getAccessSettings()->getPasswordEnabled();
   133         $test_behaviour_settings = $this->main_settings->getTestBehaviourSettings();
   135         if ($exam_conditions_enabled && $password_enabled) {
   136             $message_box_message_elements[] = $this->
lng->txt(
'tst_launcher_status_message_conditions_and_password');
   137         } elseif ($exam_conditions_enabled) {
   138             $message_box_message_elements[] = $this->
lng->txt(
'tst_launcher_status_message_conditions');
   139         } elseif ($password_enabled) {
   140             $message_box_message_elements[] = $this->
lng->txt(
'tst_launcher_status_message_password');
   144             $message_box_message_elements[] = sprintf(
   145                 $this->
lng->txt(
'tst_time_limit_message'),
   146                 $test_behaviour_settings->getProcessingTimeAsMinutes()
   150         $nr_of_tries = $this->
object->getNrOfTries();
   152         if ($nr_of_tries !== 0) {
   153             $message_box_message_elements[] = sprintf($this->
lng->txt(
'tst_attempt_limit_message'), $nr_of_tries);
   156         if ($this->
object->isStartingTimeEnabled() && !$this->
object->startingTimeReached()) {
   157             $message_box_message_elements[] = sprintf(
   158                 $this->
lng->txt(
'detail_starting_time_not_reached'),
   163         if ($this->
object->isEndingTimeEnabled() && !$this->
object->endingTimeReached()) {
   164             $message_box_message_elements[] = sprintf(
   165                 $this->
lng->txt(
'tst_exam_ending_time_message'),
   170         foreach ($message_box_message_elements as $message_box_message_element) {
   171             $message_box_message .= 
' ' . $message_box_message_element;
   174         if (!empty($message_box_message)) {
   175             $elements[] = $this->ui_factory->messageBox()->info($message_box_message);
   183         $introduction = $this->
object->getIntroduction();
   186             $this->main_settings->getIntroductionSettings()->getIntroductionEnabled() &&
   187             !empty($introduction)
   189             $this->content_style->gui()->addCss($this->tpl, $this->ref_id);
   190             $elements[] = $this->ui_factory->panel()->standard(
   191                 $this->
lng->txt(
'tst_introduction'),
   192                 $this->ui_factory->legacy($introduction),
   207         $launcher_factory = $this->ui_factory->launcher();
   209         if ($this->
object->isStartingTimeEnabled() && !$this->
object->startingTimeReached()) {
   210             return $launcher_factory
   211                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   212                 ->withButtonLabel(sprintf(
   213                     $this->
lng->txt(
'detail_starting_time_not_reached'),
   219         if ($this->
object->isEndingTimeEnabled() && $this->
object->endingTimeReached()) {
   220             return $launcher_factory
   221                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   222                 ->withButtonLabel(sprintf(
   223                     $this->
lng->txt(
'detail_ending_time_reached'),
   230             return $launcher_factory
   231                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   232                 ->withButtonLabel($this->
lng->txt(
'tst_out_of_time_message'), 
false)
   236         $participant_access = $this->test_access->isParticipantAllowed(
   241         if ($participant_access === ParticipantAccess::NOT_INVITED) {
   242             return $launcher_factory
   243                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   244                 ->withButtonLabel($this->
lng->txt(
'tst_exam_not_assigned_participant_disclaimer'), 
false)
   248         if ($participant_access !== ParticipantAccess::ALLOWED) {
   249             return $launcher_factory
   250                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   251                 ->withButtonLabel($participant_access->getAccessForbiddenMessage($this->lng), 
false)
   256             return $launcher_factory
   257                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   258                 ->withButtonLabel($this->
lng->txt(
'tst_launcher_button_label_passes_limit_reached'), 
false);
   262             return $launcher_factory
   263                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   264                 ->withButtonLabel($this->
lng->txt(
'tst_already_passed_cannot_retake'), 
false)
   268         $next_pass_allowed_timestamp = 0;
   269         if (!$this->
object->isNextPassAllowed($this->test_passes_selector, $next_pass_allowed_timestamp)) {
   270             return $launcher_factory
   271                 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
   274                         $this->
lng->txt(
'wait_for_next_pass_hint_msg'),
   298         return $this->data_factory->link($this->
lng->txt(
'tst_resume_test'), $this->data_factory->uri(ILIAS_HTTP_PATH . 
'/' . 
$url));
   306                 function (
Result $result) {
   310             )->withModalSubmitLabel($this->
lng->txt(
'continue'));
   312         $request = $this->
http->request();
   313         $key = 
'launcher_id';
   314         if (array_key_exists($key, $request->getQueryParams())
   315             && $request->getQueryParams()[$key] === 
'exam_modal') {
   316             $launcher = $launcher->withRequest($request);
   323         $uri = $this->data_factory->uri($this->
http->request()->getUri()->__toString())->withParameter(
'launcher_id', 
'exam_modal');
   324         return $this->data_factory->link($this->
lng->txt(
'tst_exam_start'), $uri);
   329         if ($this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled()) {
   330             $modal_inputs[
'exam_conditions'] = $this->ui_factory->input()->field()->checkbox(
   331                 $this->
lng->txt(
'tst_exam_conditions'),
   332                 $this->
lng->txt(
'tst_exam_conditions_label')
   333             )->withRequired(
true);
   336         if ($this->main_settings->getAccessSettings()->getPasswordEnabled()) {
   337             $modal_inputs[
'exam_password'] = $this->ui_factory->input()->field()->password(
   338                 $this->
lng->txt(
'tst_exam_password'),
   339                 $this->
lng->txt(
'tst_exam_password_label')
   340             )->withRevelation(
true)
   342             ->withAdditionalTransformation(
   343                 $this->
refinery->custom()->transformation(
   344                     static function (
Password $value): 
string {
   351         if ($this->
user->isAnonymous()) {
   352             $access_code_input = $this->ui_factory->input()->field()->text(
   353                 $this->
lng->txt(
'tst_exam_access_code'),
   354                 $this->
lng->txt(
'tst_exam_access_code_label')
   357             $access_code_from_session = $this->test_session->getAccessCodeFromSession();
   358             if ($access_code_from_session) {
   359                 $access_code_input = $access_code_input->withValue($access_code_from_session);
   362             $modal_inputs[
'exam_access_code'] = $access_code_input;
   365         if ($this->main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed()
   366             && $this->test_passes_selector->getLastFinishedPass() >= 0) {
   367             $modal_inputs[
'exam_use_previous_answers'] = $this->ui_factory->input()->field()->checkbox(
   368                 $this->
lng->txt(
'tst_exam_use_previous_answers'),
   369                 $this->
lng->txt(
'tst_exam_use_previous_answers_label')
   373         return $modal_inputs ?? [];
   378         $exam_conditions_enabled = $this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled();
   379         $password_enabled = $this->main_settings->getAccessSettings()->getPasswordEnabled();
   381         if ($exam_conditions_enabled && $password_enabled) {
   382             $modal_message_box_message = $this->
lng->txt(
'tst_exam_modal_message_conditions_and_password');
   383         } elseif ($exam_conditions_enabled) {
   384             $modal_message_box_message = $this->
lng->txt(
'tst_exam_modal_message_conditions');
   385         } elseif ($password_enabled) {
   386             $modal_message_box_message = $this->
lng->txt(
'tst_exam_modal_message_password');
   389         return isset($modal_message_box_message) ? $this->ui_factory->messageBox()->info($modal_message_box_message) : null;
   398         return $this->data_factory->link($this->
lng->txt(
'tst_exam_start'), $this->data_factory->uri(ILIAS_HTTP_PATH . 
'/' . 
$url));
   403         if ($result->
isOK()) {
   404             $conditions_met = 
true;
   406             $access_settings_password = $this->main_settings->getAccessSettings()->getPassword();
   407             $anonymous = $this->
user->isAnonymous();
   408             foreach ($result->
value() as $key => $value) {
   411                     case 'exam_conditions':
   412                         $exam_conditions_value = (bool) $value;
   413                         if (!$exam_conditions_value) {
   414                             $conditions_met = 
false;
   415                             $message .= $this->
lng->txt(
'tst_exam_conditions_not_checked_message') . 
'<br>';
   418                     case 'exam_password':
   420                         $exam_password_valid = ($password === $access_settings_password);
   421                         if (!$exam_password_valid) {
   422                             $conditions_met = 
false;
   423                             $message .= $this->
lng->txt(
'tst_exam_password_invalid_message') . 
'<br>';
   424                             if ($this->
object->getTestLogger()->isLoggingEnabled()
   425                                 && !$this->
object->getAnonymity()) {
   426                                 $logger = $this->
object->getTestLogger();
   427                                 $logger->logParticipantInteraction(
   428                                     $logger->getInteractionFactory()->buildParticipantInteraction(
   431                                         $this->
user->getId(),
   433                                         TestParticipantInteractionTypes::WRONG_TEST_PASSWORD_PROVIDED,
   439                         $this->password_checker->setUserEnteredPassword($password);
   441                     case 'exam_access_code':
   442                         if ($anonymous && !empty($value)) {
   443                             $this->test_session->setAccessCodeToSession($value);
   445                             $this->test_session->unsetAccessCodeInSession();
   448                     case 'exam_use_previous_answers':
   449                         $exam_use_previous_answers_value = (string) (
int) $value;
   454             if ($message !== 
'') {
   458             if (empty($result->
value())) {
   459                 $this->tpl->setOnScreenMessage(
   461                     $this->
lng->txt(
'tst_exam_required_fields_not_filled_message'),
   464             } elseif ($conditions_met) {
   467                     $this->main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed()
   469                     $this->
user->setPref(
'tst_use_previous_answers', $exam_use_previous_answers_value ?? 
'0');
   470                     $this->
user->update();
   473                 if (isset($password) && $password === $access_settings_password) {
   477                     $this->test_session->setPasswordChecked(
false);
   480                 $this->
ctrl->redirectByClass(
   486             $this->tpl->setOnScreenMessage(
   488                 $this->
lng->txt(
'tst_exam_required_fields_not_filled_message'),
   496         if ($this->
object->getOfflineStatus()
   497             || !$this->
object->isComplete($this->
object->getQuestionSetConfig())) {
   506         $test_behaviour_settings = $this->
object->getMainSettings()->getTestBehaviourSettings();
   507         if (!$test_behaviour_settings->getProcessingTimeEnabled()
   508             || $test_behaviour_settings->getResetProcessingTime()) {
   512         $active_id = $this->test_passes_selector->getActiveId();
   513         $last_started_pass = $this->test_session->getLastStartedPass();
   514         return $last_started_pass !== null
   515             && $this->
object->isMaxProcessingTimeReached(
   516                 $this->
object->getStartingTimeOfUser($active_id, $last_started_pass),
   523         if ($this->main_settings->getTestBehaviourSettings()->getBlockAfterPassedEnabled()) {
   524             return $this->test_passes_selector->getLastFinishedPass() >= 0
   525                 && $this->test_passes_selector->hasTestPassedOnce($this->test_session->getActiveId());
   533         $nr_of_tries = $this->
object->getNrOfTries();
   535         return $nr_of_tries === 0 || (count($this->test_passes_selector->getExistingPasses()) <= $nr_of_tries && count($this->test_passes_selector->getClosedPasses()) < $nr_of_tries);
   540         return (count($this->test_passes_selector->getExistingPasses()) - count($this->test_passes_selector->getClosedPasses())) === 1;
   546             $this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled()
   547             || $this->main_settings->getAccessSettings()->getPasswordEnabled()
   548             || $this->main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed()
   549                 && $this->test_passes_selector->getLastFinishedPass() >= 0
   550             || $this->
user->isAnonymous()
   556         $message = $this->
lng->txt(
'tst_skl_level_thresholds_missing');
   562         $link = $this->ui_factory->link()->standard(
   563             $this->
lng->txt(
'tst_skl_level_thresholds_link'),
   567         return $this->ui_factory->messageBox()->failure($message)->withLinks([$link]);
   572         if (!$this->
object->isSkillServiceEnabled()) {
   576         $questionContainerId = $this->
object->getId();
   578         $assignmentList = new \ilAssQuestionSkillAssignmentList($this->database);
   579         $assignmentList->setParentObjId($questionContainerId);
   580         $assignmentList->loadFromDb();
   582         foreach ($assignmentList->getUniqueAssignedSkills() as 
$data) {
   583             foreach (
$data[
'skill']->getLevelData() as $level) {
   584                 $threshold = new \ilTestSkillLevelThreshold($this->database);
   585                 $threshold->setTestId($this->
object->getTestId());
   586                 $threshold->setSkillBaseId(
$data[
'skill_base_id']);
   587                 $threshold->setSkillTrefId(
$data[
'skill_tref_id']);
   588                 $threshold->setSkillLevelId($level[
'id']);
   590                 if (!$threshold->dbRecordExists()) {
   601         $target = array_merge([
'ilRepositoryGUI', 
'ilObjTestGUI'], [
'ilTestSkillAdministrationGUI', 
'ilTestSkillLevelThresholdsGUI']);
   602         return $this->
ctrl->getLinkTargetByClass($target, $cmd);
 
isOK()
Get to know if the result is ok. 
 
handleRenderMessageBox(array $elements)
 
handleRenderIntroduction(array $elements)
 
isUserOutOfProcessingTime()
 
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ilObjUser $user=null,)
 
value()
Get the encapsulated value. 
 
blockUserAfterHavingPassed()
 
areSkillLevelThresholdsMissing()
 
A password is used as part of credentials for authentication. 
 
ilTestPasswordChecker $password_checker
 
readonly ilTestSession $test_session
 
static http()
Fetches the global http state from ILIAS. 
 
getModalLauncherMessageBox()
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
buildLinkTarget(string $cmd=null)
 
readonly MainSettings $main_settings
 
const CMD_SHOW_SKILL_THRESHOLDS
 
TestParticipantInteractionTypes
 
handleRenderLauncher(array $elements)
 
evaluateLauncherModalForm(Result $result)
 
readonly ilTestPassesSelector $test_passes_selector
 
getSkillLevelThresholdsMissingInfo()
 
readonly DataFactory $data_factory
 
const MESSAGE_TYPE_FAILURE
 
__construct(private readonly \ilObjTest $object, private readonly \ilObjUser $user, private readonly UIFactory $ui_factory, private readonly UIRenderer $ui_renderer, private readonly \ilLanguage $lng, private readonly Refinery $refinery, private readonly \ilCtrlInterface $ctrl, private readonly \ilGlobalTemplateInterface $tpl, private readonly ContentStyle $content_style, private readonly HTTPServices $http, private readonly TabsManager $tabs_manager, private readonly \ilAccessHandler $access, private readonly \ilTestAccess $test_access, private readonly \ilDBInterface $database, private readonly \ilRbacSystem $rbac_system)
 
static set(string $a_var, $a_val)
Set a value.