ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilTestQuestionNavigationGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
24 
32 {
33  public const SHOW_DISABLED_COMMANDS = false;
34 
35  public const CSS_CLASS_SUBMIT_BUTTONS = 'ilc_qsubmit_Submit';
36  private \ILIAS\DI\UIServices $ui;
37 
41  private $editSolutionCommand = '';
42 
46  private $questionWorkedThrough = false;
47 
51  private $submitSolutionCommand = '';
52 
53  // fau: testNav - new variable for 'revert changes' link target
58  // fau.
59 
64 
69 
74 
78  private $answerFreezingEnabled = false;
79 
84 
88  private $requestHintCommand = '';
89 
93  private $showHintsCommand = '';
94 
98  private $hintRequestsExist = false;
99 
100  // fau: testNav - change question mark command to link target
105  // fau.
106 
110  private $questionMarked = false;
111 
115  private $anythingRendered = false;
116 
122  public function __construct(
123  protected ilLanguage $lng,
124  protected UIFactory $ui_factory,
125  protected UIRenderer $ui_renderer
126  ) {
127  }
128 
132  public function getEditSolutionCommand(): string
133  {
135  }
136 
141  {
142  $this->editSolutionCommand = $editSolutionCommand;
143  }
144 
148  public function isQuestionWorkedThrough(): bool
149  {
151  }
152 
157  {
158  $this->questionWorkedThrough = $questionWorkedThrough;
159  }
160 
164  public function getSubmitSolutionCommand(): string
165  {
167  }
168 
173  {
174  $this->submitSolutionCommand = $submitSolutionCommand;
175  }
176 
177  // fau: testNav - get/set revertChangesCommand
181  public function getRevertChangesLinkTarget(): string
182  {
184  }
185 
190  {
191  $this->revertChangesLinkTarget = $revertChangesLinkTarget;
192  }
193  // fau.
194 
198  public function isDiscardSolutionButtonEnabled(): bool
199  {
201  }
202 
207  {
208  $this->discardSolutionButtonEnabled = $discardSolutionButtonEnabled;
209  }
210 
214  public function getSkipQuestionLinkTarget(): string
215  {
217  }
218 
223  {
224  $this->skipQuestionLinkTarget = $skipQuestionLinkTarget;
225  }
226 
230  public function getInstantFeedbackCommand(): string
231  {
233  }
234 
239  {
240  $this->instantFeedbackCommand = $instantFeedbackCommand;
241  }
242 
246  public function isAnswerFreezingEnabled(): bool
247  {
249  }
250 
254  public function isForceInstantResponseEnabled(): bool
255  {
257  }
258 
263  {
264  $this->forceInstantResponseEnabled = $forceInstantResponseEnabled;
265  }
266 
271  {
272  $this->answerFreezingEnabled = $answerFreezingEnabled;
273  }
274 
278  public function getRequestHintCommand(): string
279  {
281  }
282 
287  {
288  $this->requestHintCommand = $requestHintCommand;
289  }
290 
294  public function getShowHintsCommand(): string
295  {
297  }
298 
303  {
304  $this->showHintsCommand = $showHintsCommand;
305  }
306 
310  public function hintRequestsExist(): bool
311  {
313  }
314 
319  {
321  }
322 
323  // fau: testNav - change setter/getter of question mark command to link target
327  public function getQuestionMarkLinkTarget(): string
328  {
330  }
331 
336  {
337  $this->questionMarkLinkTarget = $questionMarkLinkTarget;
338  }
339  // fau.
340 
344  public function isQuestionMarked(): bool
345  {
346  return $this->questionMarked;
347  }
348 
353  {
354  $this->questionMarked = $questionMarked;
355  }
356 
360  public function isAnythingRendered(): bool
361  {
363  }
364 
368  public function setAnythingRendered()
369  {
370  $this->anythingRendered = true;
371  }
372 
373  public function getActionsHTML(): string
374  {
375  $tpl = $this->getTemplate('actions');
376  $actions = [];
377 
378  if ($this->getQuestionMarkLinkTarget()) {
379  $this->renderActionsIcon(
380  $tpl,
381  $this->getQuestionMarkIconSource(),
382  $this->getQuestionMarkIconLabel(),
383  'ilTestMarkQuestionIcon'
384  );
385  $target = $this->getQuestionMarkLinkTarget();
386  $actions[] = $this->ui_factory->button()->shy(
388  ''
389  )->withAdditionalOnLoadCode(
390  static function (string $id) use ($target): string {
391  return "document.getElementById('$id').addEventListener('click', "
392  . '(e) => {'
393  . " il.TestPlayerQuestionEditControl.checkNavigation('{$target}', 'show', e);"
394  . '});';
395  }
396  );
397  }
398 
399  if ($this->getSkipQuestionLinkTarget()) {
400  $actions[] = $this->ui_factory->button()->shy(
401  $this->lng->txt('postpone_question'),
403  );
404  }
405 
406  if ($actions !== []) {
407  $actions[] = $this->ui_factory->divider()->horizontal();
408  }
409 
410  $actions[] = $this->ui_factory->button()->shy(
411  $this->lng->txt('tst_revert_changes'),
413  )->withUnavailableAction(!$this->getRevertChangesLinkTarget());
414 
415  $actions[] = $this->ui_factory->button()->shy(
416  $this->lng->txt('discard_answer'),
417  '#'
418  )
419  ->withUnavailableAction(!$this->isDiscardSolutionButtonEnabled())
421  fn($id) => "document.getElementById('$id').addEventListener(
422  'click',
423  ()=>$('#tst_discard_solution_modal').modal('show')
424  )"
425  );
426 
427  $list = $this->ui_factory->dropdown()->standard($actions)->withLabel($this->lng->txt("actions"));
428  $tpl->setVariable('ACTION_MENU', $this->ui_renderer->render($list));
429 
430  return $tpl->get();
431  }
432 
433 
437  public function getHTML(): string
438  {
439  // fau: testNav - add parameter for toolbar template purpose
440  $tpl = $this->getTemplate('toolbar');
441  // fau.
442  if ($this->getEditSolutionCommand()) {
443  $this->renderSubmitButton(
444  $tpl,
445  $this->getEditSolutionCommand(),
447  );
448  }
449 
450  // fau: testNav - don't show the standard submit button.
451  // fau: testNav - discard answer is moved to the actions menu.
452  // fau: testNav - skip question (postpone) is moved to the actions menu.
453 
454  if ($this->getInstantFeedbackCommand()) {
456  $tpl,
457  $this->getInstantFeedbackCommand(),
458  $this->getCheckButtonLabel(),
460  );
461  }
462 
463  if ($this->getRequestHintCommand()) {
464  $this->renderSubmitButton(
465  $tpl,
466  $this->getRequestHintCommand(),
468  );
469  }
470 
471  if ($this->getShowHintsCommand()) {
472  $this->renderSubmitButton(
473  $tpl,
474  $this->getShowHintsCommand(),
475  $this->lng->txt('show_requested_question_hints')
476  );
477  }
478 
479  // fau: testNav - question mark is moved to the actions menu.
480  // fau: testNav - char selector is moved to the actions menu.
481 
482  if ($this->isAnythingRendered()) {
483  $this->parseNavigation($tpl);
484  }
485 
486  return $tpl->get();
487  }
488 
489  private function getEditSolutionButtonLabel(): string
490  {
491  if ($this->isQuestionWorkedThrough()) {
492  return $this->lng->txt('edit_answer');
493  }
494 
495  return $this->lng->txt('answer_question');
496  }
497 
498  private function getCheckButtonLabel(): string
499  {
500  if ($this->isAnswerFreezingEnabled()) {
501  return $this->lng->txt('submit_and_check');
502  }
503 
504  return $this->lng->txt('check');
505  }
506 
507  private function getRequestHintButtonLabel(): string
508  {
509  if ($this->hintRequestsExist()) {
510  return $this->lng->txt('button_request_next_question_hint');
511  }
512 
513  return $this->lng->txt('button_request_question_hint');
514  }
515 
516  // fau: testNav - adjust mark icon and action labels
517  private function getQuestionMarkActionLabel(): string
518  {
519  if ($this->isQuestionMarked()) {
520  return $this->lng->txt('tst_remove_mark');
521  }
522 
523  return $this->lng->txt('tst_question_mark');
524  }
525 
526 
527  private function getQuestionMarkIconLabel(): string
528  {
529  if ($this->isQuestionMarked()) {
530  return $this->lng->txt('tst_question_marked');
531  }
532 
533  return$this->lng->txt('tst_question_not_marked');
534  }
535  // fau.
536 
537  private function getQuestionMarkIconSource(): string
538  {
539  if ($this->isQuestionMarked()) {
540  return ilUtil::getImagePath('object/marked.svg');
541  }
542 
543  return ilUtil::getImagePath('object/marked_.svg');
544  }
545 
546  // fau: testNav - add parameter for template purpose
552  private function getTemplate($a_purpose = 'toolbar'): ilTemplate
553  {
554  switch ($a_purpose) {
555  case 'toolbar':
556  return new ilTemplate(
557  'tpl.tst_question_navigation.html',
558  true,
559  true,
560  'Modules/Test'
561  );
562  default:
563  case 'actions':
564  return new ilTemplate(
565  'tpl.tst_question_actions.html',
566  true,
567  true,
568  'Modules/Test'
569  );
570  }
571  }
572  // fau.
573 
577  private function parseNavigation(ilTemplate $tpl)
578  {
579  $tpl->setCurrentBlock('question_related_navigation');
580  $tpl->parseCurrentBlock();
581  }
582 
586  private function parseButtonsBlock(ilTemplate $tpl)
587  {
588  $tpl->setCurrentBlock('buttons');
589  $tpl->parseCurrentBlock();
590  }
591 
596  private function renderButtonInstance(ilTemplate $tpl, Button $button)
597  {
598  $tpl->setCurrentBlock("button_instance");
599  $tpl->setVariable("BUTTON_INSTANCE", $this->ui_renderer->render($button));
600  $tpl->parseCurrentBlock();
601 
602  $this->parseButtonsBlock($tpl);
603  $this->setAnythingRendered();
604  }
605 
612  private function renderSubmitButton(
613  ilTemplate $tpl,
614  string $command,
615  string $label
616  ): void {
617  $on_load_code = $this->getOnLoadCode($command);
618  $this->renderButtonInstance(
619  $tpl,
620  $this->ui_factory->button()->standard($label, '')->withAdditionalOnLoadCode($on_load_code)
621  );
622  }
623 
624  private function renderInstantFeedbackButton(
625  ilTemplate $tpl,
626  string $command,
627  string $label,
628  bool $is_primary
629  ): void {
630  $on_load_code = $this->getOnLoadCode($command);
631  if ($is_primary) {
632  $this->renderButtonInstance(
633  $tpl,
634  $this->ui_factory->button()->primary($label, '')->withAdditionalOnLoadCode($on_load_code)
635  );
636  return;
637  }
638 
639  $this->renderButtonInstance(
640  $tpl,
641  $this->ui_factory->button()->standard($label, '')->withAdditionalOnLoadCode($on_load_code)
642  );
643  }
644 
645  private function getOnLoadCode(string $command): Closure
646  {
647  return static function ($id) use ($command): string {
648  return "document.getElementById('$id').addEventListener('click', "
649  . '(e) => {'
650  . " e.target.setAttribute('name', 'cmd[$command]');"
651  . ' e.target.form.requestSubmit(e.target);'
652  . '});';
653  };
654  }
655 
663  private function renderIcon(ilTemplate $tpl, $command, $iconSrc, $label, $cssClass)
664  {
665  $tpl->setCurrentBlock("submit_icon");
666  $tpl->setVariable("SUBMIT_ICON_CMD", $command);
667  $tpl->setVariable("SUBMIT_ICON_SRC", $iconSrc);
668  $tpl->setVariable("SUBMIT_ICON_TEXT", $label);
669  $tpl->setVariable("SUBMIT_ICON_CLASS", $cssClass);
670  $tpl->parseCurrentBlock();
671 
672  $this->parseButtonsBlock($tpl);
673  $this->setAnythingRendered();
674  }
675 
676  // fau: testNav - render an icon beneath the actions menu
677  private function renderActionsIcon(ilTemplate $tpl, $iconSrc, $label, $cssClass)
678  {
679  $tpl->setCurrentBlock("actions_icon");
680  $tpl->setVariable("ICON_SRC", $iconSrc);
681  $tpl->setVariable("ICON_TEXT", $label);
682  $tpl->setVariable("ICON_CLASS", $cssClass);
683  $tpl->parseCurrentBlock();
684  }
685  // fau.
686 }
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
renderActionsIcon(ilTemplate $tpl, $iconSrc, $label, $cssClass)
renderButtonInstance(ilTemplate $tpl, Button $button)
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
renderIcon(ilTemplate $tpl, $command, $iconSrc, $label, $cssClass)
setDiscardSolutionButtonEnabled($discardSolutionButtonEnabled)
setRevertChangesLinkTarget($revertChangesLinkTarget)
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:546
renderSubmitButton(ilTemplate $tpl, string $command, string $label)
$lng
__construct(protected ilLanguage $lng, protected UIFactory $ui_factory, protected UIRenderer $ui_renderer)
renderInstantFeedbackButton(ilTemplate $tpl, string $command, string $label, bool $is_primary)
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
setForceInstantResponseEnabled($forceInstantResponseEnabled)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
getTemplate($a_purpose='toolbar')
Get the template.