ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilTestQuestionNavigationGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
26 
34 {
35  public const SHOW_DISABLED_COMMANDS = false;
36 
37  public const CSS_CLASS_SUBMIT_BUTTONS = 'ilc_qsubmit_Submit';
38  private \ILIAS\DI\UIServices $ui;
39 
40  private string $edit_solution_command = '';
41  private bool $question_worked_through = false;
42  private string $revert_changes_link_target = '';
43  private bool $discard_solution_button_enabled = false;
44  private string $skip_question_link_target = '';
45  private string $instant_feedback_command = '';
46  private bool $answer_freezing_enabled = false;
47  private bool $force_instant_response_enabled = false;
48  private string $question_mark_link_target = '';
49  private bool $question_marked = false;
50  private bool $anything_rendered = false;
52 
53  public function __construct(
54  protected ilLanguage $lng,
55  protected UIFactory $ui_factory,
56  protected UIRenderer $ui_renderer
57  ) {
58  }
59 
60  public function setEditSolutionCommand(string $edit_solution_command): void
61  {
62  $this->edit_solution_command = $edit_solution_command;
63  }
64 
65  public function setQuestionWorkedThrough(bool $question_worked_through): void
66  {
67  $this->question_worked_through = $question_worked_through;
68  }
69 
70  public function setRevertChangesLinkTarget(string $revert_changes_link_target): void
71  {
72  $this->revert_changes_link_target = $revert_changes_link_target;
73  }
74 
75  public function setDiscardSolutionButtonEnabled(bool $discard_solution_button_enabled): void
76  {
77  $this->discard_solution_button_enabled = $discard_solution_button_enabled;
78  }
79 
80  public function setSkipQuestionLinkTarget(string $skip_question_link_target): void
81  {
82  $this->skip_question_link_target = $skip_question_link_target;
83  }
84 
85  public function setInstantFeedbackCommand(string $instant_feedback_command): void
86  {
87  $this->instant_feedback_command = $instant_feedback_command;
88  }
89 
90  public function setForceInstantResponseEnabled(bool $force_instant_response_enabled): void
91  {
92  $this->force_instant_response_enabled = $force_instant_response_enabled;
93  }
94 
95  public function setAnswerFreezingEnabled(bool $answer_freezing_enabled): void
96  {
97  $this->answer_freezing_enabled = $answer_freezing_enabled;
98  }
99 
100  public function setQuestionMarkLinkTarget(string $question_mark_link_target): void
101  {
102  $this->question_mark_link_target = $question_mark_link_target;
103  }
104 
105  public function setQuestionMarked(bool $question_marked): void
106  {
107  $this->question_marked = $question_marked;
108  }
109 
110  public function setAnythingRendered(): void
111  {
112  $this->anything_rendered = true;
113  }
114 
115  public function setShowDiscardModalSignal(Signal $signal): void
116  {
117  $this->show_discard_modal_signal = $signal;
118  }
119 
120  private function getShowDiscardModalSignal(): Signal
121  {
122  return $this->show_discard_modal_signal ?? new SignalImplementation('');
123  }
124 
125  public function getActionsHTML(): string
126  {
127  $tpl = $this->getTemplate('actions');
128  $actions = [];
129 
130  if ($this->question_mark_link_target) {
131  $this->renderActionsIcon(
132  $tpl,
133  $this->getQuestionMarkIconSource(),
134  $this->getQuestionMarkIconLabel(),
135  'ilTestMarkQuestionIcon'
136  );
138  $actions[] = $this->ui_factory->button()->shy(
140  ''
141  )->withAdditionalOnLoadCode(
142  static function (string $id) use ($target): string {
143  return "document.getElementById('$id').addEventListener('click', "
144  . '(e) => {'
145  . " il.TestPlayerQuestionEditControl.checkNavigation('{$target}', 'show', e);"
146  . '});';
147  }
148  );
149  }
150 
151  if ($this->skip_question_link_target) {
152  $actions[] = $this->ui_factory->button()->shy(
153  $this->lng->txt('postpone_question'),
155  );
156  }
157 
158  if ($actions !== []) {
159  $actions[] = $this->ui_factory->divider()->horizontal();
160  }
161 
162  $actions[] = $this->ui_factory->button()->shy(
163  $this->lng->txt('tst_revert_changes'),
165  )->withUnavailableAction(!$this->revert_changes_link_target);
166 
167  if ($this->question_worked_through) {
168  $actions[] = $this->ui_factory->button()->shy(
169  $this->lng->txt('discard_answer'),
170  '#'
171  )->withUnavailableAction(!$this->discard_solution_button_enabled)
172  ->withOnClick($this->getShowDiscardModalSignal());
173  }
174 
175  $list = $this->ui_factory->dropdown()->standard($actions)->withLabel($this->lng->txt('actions'));
176  $tpl->setVariable('ACTION_MENU', $this->ui_renderer->render($list));
177 
178  return $tpl->get();
179  }
180 
181  public function getHTML(): string
182  {
183  $tpl = $this->getTemplate('toolbar');
184  if ($this->edit_solution_command) {
185  $this->renderSubmitButton(
186  $tpl,
187  $this->edit_solution_command,
189  );
190  }
191 
192  if ($this->instant_feedback_command === ilTestPlayerCommands::SHOW_INSTANT_RESPONSE) {
194  $tpl,
195  $this->instant_feedback_command,
196  $this->getCheckButtonLabel(),
197  $this->force_instant_response_enabled
198  );
199  }
200 
201  if ($this->anything_rendered) {
202  $this->parseNavigation($tpl);
203  }
204 
205  return $tpl->get();
206  }
207 
208  private function getEditSolutionButtonLabel(): string
209  {
210  if ($this->question_worked_through) {
211  return $this->lng->txt('edit_answer');
212  }
213 
214  return $this->lng->txt('answer_question');
215  }
216 
217  private function getCheckButtonLabel(): string
218  {
219  if ($this->answer_freezing_enabled) {
220  return $this->lng->txt('submit_and_check');
221  }
222 
223  return $this->lng->txt('check');
224  }
225 
226  private function getQuestionMarkActionLabel(): string
227  {
228  if ($this->question_marked) {
229  return $this->lng->txt('tst_remove_mark');
230  }
231 
232  return $this->lng->txt('tst_question_mark');
233  }
234 
235 
236  private function getQuestionMarkIconLabel(): string
237  {
238  if ($this->question_marked) {
239  return $this->lng->txt('tst_question_marked');
240  }
241 
242  return$this->lng->txt('tst_question_not_marked');
243  }
244 
245  private function getQuestionMarkIconSource(): string
246  {
247  if ($this->question_marked) {
248  return ilUtil::getImagePath('object/marked.svg');
249  }
250 
251  return ilUtil::getImagePath('object/marked_.svg');
252  }
253 
254  private function getTemplate($a_purpose = 'toolbar'): ilTemplate
255  {
256  switch ($a_purpose) {
257  case 'toolbar':
258  return new ilTemplate(
259  'tpl.tst_question_navigation.html',
260  true,
261  true,
262  'components/ILIAS/Test'
263  );
264  default:
265  case 'actions':
266  return new ilTemplate(
267  'tpl.tst_question_actions.html',
268  true,
269  true,
270  'components/ILIAS/Test'
271  );
272  }
273  }
274 
275  private function parseNavigation(ilTemplate $tpl): void
276  {
277  $tpl->setCurrentBlock('question_related_navigation');
278  $tpl->parseCurrentBlock();
279  }
280 
281  private function parseButtonsBlock(ilTemplate $tpl): void
282  {
283  $tpl->setCurrentBlock('buttons');
284  $tpl->parseCurrentBlock();
285  }
286 
287  private function renderButtonInstance(ilTemplate $tpl, Button $button): void
288  {
289  $tpl->setCurrentBlock('button_instance');
290  $tpl->setVariable('BUTTON_INSTANCE', $this->ui_renderer->render($button));
291  $tpl->parseCurrentBlock();
292 
293  $this->parseButtonsBlock($tpl);
294  $this->setAnythingRendered();
295  }
296 
297  private function renderSubmitButton(
298  ilTemplate $tpl,
299  string $command,
300  string $label
301  ): void {
302  $on_load_code = $this->getOnLoadCode($command);
303  $this->renderButtonInstance(
304  $tpl,
305  $this->ui_factory->button()->standard($label, '')->withAdditionalOnLoadCode($on_load_code)
306  );
307  }
308 
309  private function renderInstantFeedbackButton(
310  ilTemplate $tpl,
311  string $command,
312  string $label,
313  bool $is_primary
314  ): void {
315  $on_load_code = $this->getOnLoadCode($command);
316  if ($is_primary) {
317  $this->renderButtonInstance(
318  $tpl,
319  $this->ui_factory->button()->primary($label, '')->withAdditionalOnLoadCode($on_load_code)
320  );
321  return;
322  }
323 
324  $this->renderButtonInstance(
325  $tpl,
326  $this->ui_factory->button()->standard($label, '')->withAdditionalOnLoadCode($on_load_code)
327  );
328  }
329 
330  private function getOnLoadCode(string $command): Closure
331  {
332  return static function ($id) use ($command): string {
333  return "document.getElementById('$id').addEventListener('click', "
334  . '(e) => {'
335  . " e.target.setAttribute('name', 'cmd[$command]');"
336  . ' e.target.form.requestSubmit(e.target);'
337  . '});';
338  };
339  }
340 
341  private function renderActionsIcon(
342  ilTemplate $tpl,
343  string $icon_src,
344  string $label,
345  string $css_class
346  ): void {
347  $tpl->setCurrentBlock('actions_icon');
348  $tpl->setVariable('ICON_SRC', $icon_src);
349  $tpl->setVariable('ICON_TEXT', $label);
350  $tpl->setVariable('ICON_CLASS', $css_class);
351  $tpl->parseCurrentBlock();
352  }
353 }
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
setRevertChangesLinkTarget(string $revert_changes_link_target)
setSkipQuestionLinkTarget(string $skip_question_link_target)
setDiscardSolutionButtonEnabled(bool $discard_solution_button_enabled)
setEditSolutionCommand(string $edit_solution_command)
renderActionsIcon(ilTemplate $tpl, string $icon_src, string $label, string $css_class)
renderButtonInstance(ilTemplate $tpl, Button $button)
setForceInstantResponseEnabled(bool $force_instant_response_enabled)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
setAnswerFreezingEnabled(bool $answer_freezing_enabled)
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:544
renderSubmitButton(ilTemplate $tpl, string $command, string $label)
__construct(protected ilLanguage $lng, protected UIFactory $ui_factory, protected UIRenderer $ui_renderer)
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
renderInstantFeedbackButton(ilTemplate $tpl, string $command, string $label, bool $is_primary)
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
setInstantFeedbackCommand(string $instant_feedback_command)
setQuestionWorkedThrough(bool $question_worked_through)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
global $lng
Definition: privfeed.php:31
setQuestionMarkLinkTarget(string $question_mark_link_target)