19 declare(strict_types=1);
57 private readonly
ilCtrl $ctrl,
59 private readonly ContentStyle $content_style,
66 $this->ref_id = $this->
object->getRefId();
67 $this->main_settings = $this->
object->getMainSettings();
73 $this->test_passes_selector->setActiveId($this->test_session->getActiveId());
74 $this->test_passes_selector->setLastFinishedPass($this->test_session->getLastFinishedPass());
80 if ($this->
access->checkAccess(
'read',
'', $this->ref_id)) {
81 $this->{$this->
ctrl->getCmd(self::DEFAULT_CMD)}();
85 if (!$this->
object->getMainSettings()->getAdditionalSettings()->getHideInfoTab()) {
86 $this->
ctrl->redirectByClass(ilObjTestGUI::class,
'infoScreen');
89 $this->tpl->setOnScreenMessage(
'failure', sprintf(
90 $this->
lng->txt(
'msg_no_perm_read_item'),
91 $this->
object->getTitle()
94 $this->
ctrl->redirectByClass(
'ilrepositorygui');
110 $this->tpl->setContent(
111 $this->ui_renderer->render(
119 $message_box_message =
'';
120 $message_box_message_elements = [];
122 $exam_conditions_enabled = $this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled();
123 $password_enabled = $this->main_settings->getAccessSettings()->getPasswordEnabled();
124 $test_behaviour_settings = $this->main_settings->getTestBehaviourSettings();
126 if ($exam_conditions_enabled && $password_enabled) {
127 $message_box_message_elements[] = $this->
lng->txt(
'tst_launcher_status_message_conditions_and_password');
128 } elseif ($exam_conditions_enabled) {
129 $message_box_message_elements[] = $this->
lng->txt(
'tst_launcher_status_message_conditions');
130 } elseif ($password_enabled) {
131 $message_box_message_elements[] = $this->
lng->txt(
'tst_launcher_status_message_password');
135 $message_box_message_elements[] = sprintf(
136 $this->
lng->txt(
'tst_time_limit_message'),
137 $test_behaviour_settings->getProcessingTimeAsMinutes()
141 $nr_of_tries = $this->
object->getNrOfTries();
143 if ($nr_of_tries !== 0) {
144 $message_box_message_elements[] = sprintf($this->
lng->txt(
'tst_attempt_limit_message'), $nr_of_tries);
147 if ($this->
object->isStartingTimeEnabled() && !$this->
object->startingTimeReached()) {
148 $message_box_message_elements[] = sprintf(
149 $this->
lng->txt(
'detail_starting_time_not_reached'),
154 if ($this->
object->isEndingTimeEnabled() && !$this->
object->endingTimeReached()) {
155 $message_box_message_elements[] = sprintf(
156 $this->
lng->txt(
'tst_exam_ending_time_message'),
161 foreach ($message_box_message_elements as $message_box_message_element) {
162 $message_box_message .=
' ' . $message_box_message_element;
165 if (!empty($message_box_message)) {
166 $elements[] = $this->ui_factory->messageBox()->info($message_box_message);
174 $introduction = $this->
object->getIntroduction();
177 $this->main_settings->getIntroductionSettings()->getIntroductionEnabled() &&
178 !empty($introduction)
180 $this->content_style->gui()->addCss($this->tpl, $this->ref_id);
181 $elements[] = $this->ui_factory->panel()->standard(
182 $this->
lng->txt(
'tst_introduction'),
183 $this->ui_factory->legacy($introduction),
198 $launcher_factory = $this->ui_factory->launcher();
200 if ($this->
object->isStartingTimeEnabled() && !$this->
object->startingTimeReached()) {
201 return $launcher_factory
202 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
203 ->withButtonLabel(sprintf(
204 $this->
lng->txt(
'detail_starting_time_not_reached'),
210 if ($this->
object->isEndingTimeEnabled() && $this->
object->endingTimeReached()) {
211 return $launcher_factory
212 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
213 ->withButtonLabel(sprintf(
214 $this->
lng->txt(
'detail_ending_time_reached'),
221 return $launcher_factory
222 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
223 ->withButtonLabel($this->
lng->txt(
'tst_out_of_time_message'),
false)
227 if ($this->
object->getFixedParticipants() && $this->
object->getInvitedUsers($this->
user->getId()) === []) {
228 return $launcher_factory
229 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
230 ->withButtonLabel($this->
lng->txt(
'tst_exam_not_assigned_participant_disclaimer'),
false)
235 return $launcher_factory
236 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
237 ->withButtonLabel($this->
lng->txt(
'user_wrong_clientip'),
false)
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_launcher_button_label_passes_limit_reached'),
false);
248 return $launcher_factory
249 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
250 ->withButtonLabel($this->
lng->txt(
'tst_already_passed_cannot_retake'),
false)
254 $next_pass_allowed_timestamp = 0;
255 if (!$this->
object->isNextPassAllowed($this->test_passes_selector, $next_pass_allowed_timestamp)) {
256 return $launcher_factory
257 ->inline($this->data_factory->link(
'', $this->data_factory->uri($this->http->request()->getUri()->__toString())))
260 $this->
lng->txt(
'wait_for_next_pass_hint_msg'),
281 return $this->data_factory->link($this->
lng->txt(
'tst_resume_test'), $this->data_factory->uri(ILIAS_HTTP_PATH .
'/' .
$url));
289 function (
Result $result) {
293 )->withModalSubmitLabel($this->
lng->txt(
'continue'));
295 $request = $this->
http->request();
296 $key =
'launcher_id';
297 if (array_key_exists(
$key, $request->getQueryParams())
298 && $request->getQueryParams()[
$key] ===
'exam_modal') {
299 $launcher = $launcher->withRequest($request);
306 $uri = $this->data_factory->uri($this->
http->request()->getUri()->__toString())->withParameter(
'launcher_id',
'exam_modal');
307 return $this->data_factory->link($this->
lng->txt(
'tst_exam_start'), $uri);
312 if ($this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled()) {
313 $modal_inputs[
'exam_conditions'] = $this->ui_factory->input()->field()->checkbox(
314 $this->
lng->txt(
'tst_exam_conditions'),
315 $this->
lng->txt(
'tst_exam_conditions_label')
316 )->withRequired(
true);
319 if ($this->main_settings->getAccessSettings()->getPasswordEnabled()) {
320 $modal_inputs[
'exam_password'] = $this->ui_factory->input()->field()->password(
321 $this->
lng->txt(
'tst_exam_password'),
322 $this->
lng->txt(
'tst_exam_password_label')
323 )->withRevelation(
true)
325 ->withAdditionalTransformation(
326 $this->
refinery->custom()->transformation(
328 return $value->toString();
334 if ($this->
user->isAnonymous()) {
335 $access_code_input = $this->ui_factory->input()->field()->text(
336 $this->
lng->txt(
'tst_exam_access_code'),
337 $this->
lng->txt(
'tst_exam_access_code_label')
340 $access_code_from_session = $this->test_session->getAccessCodeFromSession();
341 if ($access_code_from_session) {
342 $access_code_input = $access_code_input->withValue($access_code_from_session);
345 $modal_inputs[
'exam_access_code'] = $access_code_input;
348 if ($this->main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed()
349 && $this->test_passes_selector->getLastFinishedPass() >= 0) {
350 $modal_inputs[
'exam_use_previous_answers'] = $this->ui_factory->input()->field()->checkbox(
351 $this->
lng->txt(
'tst_exam_use_previous_answers'),
352 $this->
lng->txt(
'tst_exam_use_previous_answers_label')
356 return $modal_inputs ?? [];
361 $exam_conditions_enabled = $this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled();
362 $password_enabled = $this->main_settings->getAccessSettings()->getPasswordEnabled();
364 if ($exam_conditions_enabled && $password_enabled) {
365 $modal_message_box_message = $this->
lng->txt(
'tst_exam_modal_message_conditions_and_password');
366 } elseif ($exam_conditions_enabled) {
367 $modal_message_box_message = $this->
lng->txt(
'tst_exam_modal_message_conditions');
368 } elseif ($password_enabled) {
369 $modal_message_box_message = $this->
lng->txt(
'tst_exam_modal_message_password');
372 return isset($modal_message_box_message) ? $this->ui_factory->messageBox()->info($modal_message_box_message) : null;
378 return $this->data_factory->link($this->
lng->txt(
'tst_exam_start'), $this->data_factory->uri(ILIAS_HTTP_PATH .
'/' .
$url));
383 if ($result->
isOK()) {
384 $conditions_met =
true;
386 $access_settings_password = $this->main_settings->getAccessSettings()->getPassword();
387 $anonymous = $this->
user->isAnonymous();
388 foreach ($result->
value() as
$key => $value) {
391 case 'exam_conditions':
392 $exam_conditions_value = (bool) $value;
393 if (!$exam_conditions_value) {
394 $conditions_met =
false;
395 $message .= $this->
lng->txt(
'tst_exam_conditions_not_checked_message') .
'<br>';
398 case 'exam_password':
400 $exam_password_valid = ($password === $access_settings_password);
401 if (!$exam_password_valid) {
402 $conditions_met =
false;
403 $message .= $this->
lng->txt(
'tst_exam_password_invalid_message') .
'<br>';
405 $this->password_checker->setUserEnteredPassword($password);
407 case 'exam_access_code':
408 if ($anonymous && !empty($value)) {
409 $this->test_session->setAccessCodeToSession($value);
411 $this->test_session->unsetAccessCodeInSession();
414 case 'exam_use_previous_answers':
415 $exam_use_previous_answers_value = (string) (
int) $value;
424 if (empty($result->
value())) {
426 } elseif ($conditions_met) {
429 $this->main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed()
431 $this->
user->setPref(
'tst_use_previous_answers', $exam_use_previous_answers_value ??
'0');
432 $this->
user->update();
435 if (isset($password) && $password === $access_settings_password) {
439 $this->test_session->setPasswordChecked(
false);
451 if ($this->
object->getOfflineStatus()
452 || !$this->
object->isComplete($this->
object->getQuestionSetConfig())) {
461 $test_behaviour_settings = $this->
object->getMainSettings()->getTestBehaviourSettings();
462 if (!$test_behaviour_settings->getProcessingTimeEnabled()
463 || $test_behaviour_settings->getResetProcessingTime()) {
467 $active_id = $this->test_passes_selector->getActiveId();
468 $last_started_pass = $this->test_session->getLastStartedPass();
469 return $last_started_pass !== null
470 && $this->
object->isMaxProcessingTimeReached(
471 $this->
object->getStartingTimeOfUser($active_id, $last_started_pass),
478 if ($this->main_settings->getTestBehaviourSettings()->getBlockAfterPassedEnabled()) {
479 return $this->test_passes_selector->getLastFinishedPass() >= 0
480 && $this->test_passes_selector->hasTestPassedOnce($this->test_session->getActiveId());
488 $nr_of_tries = $this->
object->getNrOfTries();
490 return $nr_of_tries === 0 || (count($this->test_passes_selector->getExistingPasses()) <= $nr_of_tries && count($this->test_passes_selector->getClosedPasses()) < $nr_of_tries);
495 return (count($this->test_passes_selector->getExistingPasses()) - count($this->test_passes_selector->getClosedPasses())) === 1;
501 $this->main_settings->getIntroductionSettings()->getExamConditionsCheckboxEnabled()
502 || $this->main_settings->getAccessSettings()->getPasswordEnabled()
503 || $this->main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed()
504 && $this->test_passes_selector->getLastFinishedPass() >= 0
505 || $this->
user->isAnonymous()
511 $message = $this->
lng->txt(
'tst_skl_level_thresholds_missing');
517 $link = $this->ui_factory->link()->standard(
518 $this->
lng->txt(
'tst_skl_level_thresholds_link'),
522 return $this->ui_factory->messageBox()->failure(
$message)->withLinks([$link]);
527 if (!$this->
object->isSkillServiceEnabled()) {
531 $questionContainerId = $this->
object->getId();
534 $assignmentList->setParentObjId($questionContainerId);
535 $assignmentList->loadFromDb();
537 foreach ($assignmentList->getUniqueAssignedSkills() as
$data) {
538 foreach (
$data[
'skill']->getLevelData() as $level) {
540 $threshold->setTestId($this->
object->getTestId());
541 $threshold->setSkillBaseId(
$data[
'skill_base_id']);
542 $threshold->setSkillTrefId(
$data[
'skill_tref_id']);
543 $threshold->setSkillLevelId($level[
'id']);
545 if (!$threshold->dbRecordExists()) {
556 $target = array_merge([
'ilRepositoryGUI',
'ilObjTestGUI'], [
'ilTestSkillAdministrationGUI',
'ilTestSkillLevelThresholdsGUI']);
557 return $this->
ctrl->getLinkTargetByClass($target, $cmd);
isOK()
Get to know if the result is ok.
readonly ilObjTestMainSettings $main_settings
readonly ilTestSession $test_session
A Link is the often used combination of a label and an URL.
value()
Get the encapsulated value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ChatMainBarProvider .
readonly DataFactory $data_factory
evaluateLauncherModalForm(Result $result)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
A result encapsulates a value or an error and simplifies the handling of those.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
A password is used as part of credentials for authentication.
areSkillLevelThresholdsMissing()
blockUserAfterHavingPassed()
readonly ilTestPassesSelector $test_passes_selector
static _lookupOnlineTestAccess($a_test_id, $a_user_id)
Checks if a user is allowd to run an online exam.
static http()
Fetches the global http state from ILIAS.
isUserOutOfProcessingTime()
const CMD_SHOW_SKILL_THRESHOLDS
getSkillLevelThresholdsMissingInfo()
__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 ilCtrl $ctrl, private readonly ilGlobalTemplateInterface $tpl, private readonly ContentStyle $content_style, private readonly HTTPServices $http, private readonly ilTabsGUI $tabs, private readonly ilAccessHandler $access, private readonly ilDBInterface $database, private readonly ilRbacSystem $rbac_system)
buildLinkTarget(string $cmd=null)
handleRenderLauncher(array $elements)
getModalLauncherMessageBox()
handleRenderMessageBox(array $elements)
ilTestPasswordChecker $password_checker
const MESSAGE_TYPE_FAILURE
handleRenderIntroduction(array $elements)
static set(string $a_var, $a_val)
Set a value.
Refinery Factory $refinery