ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.assLongMenuGUI.php
Go to the documentation of this file.
1 <?php
2 
20 use ILIAS\UI\Component\Symbol\Glyph\Factory as GlyphFactory;
21 
22 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
23 
32 {
33  private $ilTabs;
34  private GlyphFactory $glyph_factory;
36 
37  public function __construct($id = -1)
38  {
40  $this->object = new assLongMenu();
41  if ($id >= 0) {
42  $this->object->loadFromDb($id);
43  }
45  global $DIC;
46  $ilTabs = $DIC['ilTabs'];
47  $lng = $DIC['lng'];
48  $this->ilTabs = $ilTabs;
49  $this->lng = $lng;
50  $this->glyph_factory = $DIC['ui.factory']->symbol()->glyph();
51  $this->renderer = $DIC['ui.renderer'];
52 
53  }
54 
55  public function getCommand($cmd)
56  {
57  return $cmd;
58  }
59 
63  protected function writePostData(bool $always = false): int
64  {
65  $form = $this->buildEditForm();
66  $form->setValuesByPost();
67  $check = $form->checkInput() && $this->verifyAnswerOptions();
68 
69  if (!$check) {
70  $this->editQuestion($form);
71  return 1;
72  }
74  $this->writeQuestionSpecificPostData($form);
75  $custom_check = $this->object->checkQuestionCustomPart($form);
76  if (!$custom_check) {
77  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("form_input_not_valid"));
78  $this->editQuestion($form);
79  return 1;
80  }
81  $this->saveTaxonomyAssignments();
82  return 0;
83  }
84 
85  public function writeQuestionSpecificPostData(ilPropertyFormGUI $form): void
86  {
87  $min_auto_complete = (int) $form->getInput('min_auto_complete');
88  $longmenu_text = $this->request->raw('longmenu_text') ?? '';
89  $hidden_text_files = $this->request->raw('hidden_text_files') ?? '';
90  $hidden_correct_answers = $this->request->raw('hidden_correct_answers') ?? [];
91  $long_menu_type = $this->request->raw('long_menu_type') ?? [];
92  $this->object->setLongMenuTextValue(ilUtil::stripSlashes($longmenu_text));
93  $this->object->setAnswers($this->trimArrayRecursive($this->stripSlashesRecursive(json_decode($hidden_text_files))));
94  $this->object->setCorrectAnswers($this->trimArrayRecursive($this->stripSlashesRecursive(json_decode($hidden_correct_answers))));
95  $this->object->setAnswerType(ilArrayUtil::stripSlashesRecursive($long_menu_type));
96  $this->object->setQuestion($this->request->raw('question'));
97  $this->object->setLongMenuTextValue($this->request->raw('longmenu_text'));
98  $this->object->setMinAutoComplete($min_auto_complete);
99  $this->object->setIdenticalScoring($this->request->int('identical_scoring'));
100 
101  $this->saveTaxonomyAssignments();
102  }
103 
104  private function verifyAnswerOptions(): bool
105  {
106  $longmenu_text = $this->request->raw('longmenu_text') ?? '';
107  $hidden_text_files = $this->request->raw('hidden_text_files') ?? '';
108  $answer_options_from_text = preg_split(
109  "/\\[" . assLongMenu::GAP_PLACEHOLDER . " (\\d+)\\]/",
110  $longmenu_text
111  );
112 
113  $answer_options_from_files = $this->stripSlashesRecursive(json_decode($hidden_text_files));
114  if (count($answer_options_from_text) - 1 !== count($answer_options_from_files)) {
115  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('longmenu_answeroptions_differ'));
116  return false;
117  }
118 
119  $correct_answers = $this->stripSlashesRecursive(json_decode($this->request->raw('hidden_correct_answers')));
120  foreach ($correct_answers as $answer) {
121  if (!is_numeric(str_replace(',', '.', $answer[1]))) {
122  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('points_non_numeric_or_negative_msg'));
123  return false;
124  }
125  }
126  return true;
127  }
128 
129  private function stripSlashesRecursive(array $data): array
130  {
131  return array_map(
132  function (string|array $v): string|array {
133  if (is_array($v)) {
134  return $this->stripSlashesRecursive($v);
135  }
136  return ilUtil::stripSlashes($v);
137  },
138  $data
139  );
140  }
141 
142  private function trimArrayRecursive(array $data): array
143  {
144  return array_map(
145  function (string|array $v): string|array {
146  if (is_array($v)) {
147  return $this->trimArrayRecursive($v);
148  }
149  return trim($v);
150  },
151  $data
152  );
153  }
154 
155  protected function editQuestion(ilPropertyFormGUI $form = null): void
156  {
157  if ($form === null) {
158  $form = $this->buildEditForm();
159  }
160 
161  $this->getQuestionTemplate();
162 
163  $this->tpl->setVariable("QUESTION_DATA", $this->ctrl->getHTML($form));
164  }
168  protected function buildEditForm(): ilPropertyFormGUI
169  {
170  $form = $this->buildBasicEditFormObject();
171 
172  $this->addQuestionFormCommandButtons($form);
173 
174  $this->addBasicQuestionFormProperties($form);
175 
176  $this->populateQuestionSpecificFormPart($form);
177  //$this->populateAnswerSpecificFormPart($form);
178 
179  $this->populateTaxonomyFormSection($form);
180 
181  return $form;
182  }
188  {
189  $long_menu_text = new ilTextAreaInputGUI($this->lng->txt("longmenu_text"), 'longmenu_text');
190  $long_menu_text->setRequired(true);
191  //$long_menu_text->setInfo($this->lng->txt("longmenu_hint"));
192  $long_menu_text->setRows(10);
193  $long_menu_text->setCols(80);
194  if (!$this->object->getSelfAssessmentEditingMode()) {
195  if ($this->object->getAdditionalContentEditingMode() == assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_RTE) {
196  $long_menu_text->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
197  $long_menu_text->addPlugin("latex");
198  $long_menu_text->addButton("latex");
199  $long_menu_text->addButton("pastelatex");
200  $long_menu_text->setRTESupport($this->object->getId(), "qpl", "assessment");
201  $long_menu_text->setUseRte(true);
202  }
203  } else {
205  $long_menu_text->setUseTagsForRteOnly(false);
206  }
207 
208  $long_menu_text->setValue($this->object->getLongMenuTextValue());
209  $form->addItem($long_menu_text);
210 
211  $tpl = new ilTemplate("tpl.il_as_qpl_longmenu_question_gap_button_code.html", true, true, "Modules/TestQuestionPool");
212  $tpl->setVariable('INSERT_GAP', $this->lng->txt('insert_gap'));
214  $button = new ilCustomInputGUI('&nbsp;', '');
215  $button->setHtml($tpl->get());
216  $form->addItem($button);
217 
218  $modal = ilModalGUI::getInstance();
219  $modal->setHeading('');
220  $modal->setId("ilGapModal");
221  //$modal->setBackdrop(ilModalGUI::BACKDROP_OFF);
222  $modal->setBody('');
223 
224  $min_auto_complete = new ilNumberInputGUI($this->lng->txt('min_auto_complete'), 'min_auto_complete');
225 
226  $auto_complete = $this->object->getMinAutoComplete();
227  if ($auto_complete === 0) {
228  $auto_complete = assLongMenu::MIN_LENGTH_AUTOCOMPLETE;
229  }
230  $min_auto_complete->setDecimals(0);
231  $min_auto_complete->setValue($auto_complete);
232  $min_auto_complete->setMinValue(1);
233  $min_auto_complete->setMaxValue(99);
234  $min_auto_complete->setSize(5);
235  $form->addItem($min_auto_complete);
236  // identical scoring
237  $identical_scoring = new ilCheckboxInputGUI($this->lng->txt("identical_scoring"), "identical_scoring");
238  $identical_scoring->setValue(1);
239  $identical_scoring->setChecked($this->object->getIdenticalScoring());
240  $identical_scoring->setInfo($this->lng->txt('identical_scoring_desc'));
241  $identical_scoring->setRequired(false);
242  $form->addItem($identical_scoring);
243  $hidden_text = new ilHiddenInputGUI('hidden_text_files');
244  $form->addItem($hidden_text);
245 
246  $hidden_correct = new ilHiddenInputGUI('hidden_correct_answers');
247  $form->addItem($hidden_correct);
248 
249  $long_menu_language = [
250  'edit' => '[' . $this->lng->txt('edit') . ']',
251  'type' => $this->lng->txt('type'),
252  'answers' => $this->lng->txt('answers'),
253  'answer_options' => $this->lng->txt('answer_options'),
254  'correct_answers' => $this->lng->txt('correct_answers'),
255  'add_answers' => '[' . $this->lng->txt('add_answers') . ']',
256  'manual_editing' => $this->lng->txt('manual_editing')
257  ];
258 
259  $question_parts = [
260  'list' => json_decode($this->object->getJsonStructure()),
261  'gap_placeholder' => assLongMenu::GAP_PLACEHOLDER,
262  'last_updated_element' => 0,
263  'replacement_word' => '',
264  'filereader_usable' => false,
265  'max_input_fields' => assLongMenu::MAX_INPUT_FIELDS
266  ];
267  $answers = $this->object->getAnswersObject();
268 
269  if ($this->request->isset('hidden_text_files')) {
270  $question_parts['list'] = json_decode($this->request->raw('hidden_correct_answers'));
271  $answers = $this->request->raw('hidden_text_files');
272  }
273 
274  $this->tpl->addJavaScript('./Modules/TestQuestionPool/templates/default/longMenuQuestionGapBuilder.js');
275  $this->tpl->addJavaScript('./Modules/TestQuestionPool/templates/default/longMenuQuestion.js');
276  $tpl = new ilTemplate("tpl.il_as_qpl_longmenu_question_gap.html", true, true, "Modules/TestQuestionPool");
277  $tpl->setVariable('MAX_INPUT_FIELDS', assLongMenu::MAX_INPUT_FIELDS);
278  $tpl->setVariable('GAP_PLACEHOLDER', assLongMenu::GAP_PLACEHOLDER);
279  $tpl->setVariable('SELECT_BOX', $this->lng->txt('insert_gap'));
280  $tpl->setVariable("SELECT", $this->lng->txt('answers_select'));
281  $tpl->setVariable("TEXT", $this->lng->txt('answers_text_box'));
282  $tpl->setVariable("POINTS", $this->lng->txt('points'));
283  $tpl->setVariable("INFO_TEXT_UPLOAD", $this->lng->txt('info_text_upload'));
284  $tpl->setVariable("TXT_BROWSE", $this->lng->txt('select_file'));
285  $tpl->setVariable('POINTS_ERROR', $this->lng->txt('enter_enough_positive_points'));
286  $tpl->setVariable('AUTOCOMPLETE_ERROR', $this->lng->txt('autocomplete_error'));
287  $tpl->setVariable('MISSING_VALUE', $this->lng->txt('msg_input_is_required'));
288  $tpl->setVariable('SAVE', $this->lng->txt('save'));
289  $tpl->setVariable('CANCEL', $this->lng->txt('cancel'));
290  $tpl->setVariable('ADD_BUTTON', $this->renderer->render(
291  $this->glyph_factory->add()->withAction('#')
292  ));
293  $tpl->setVariable('REMOVE_BUTTON', $this->renderer->render(
294  $this->glyph_factory->remove()->withAction('#')
295  ));
296  $tag_input = new ilTagInputGUI();
297  $tag_input->setPostVar('taggable');
298  $tag_input->setJsSelfInit(false);
299  $tag_input->setTypeAheadMinLength(1);
300  $tpl->setVariable("TAGGING_PROTOTYPE", $tag_input->render(''));
301 
302  $tpl->setVariable("MY_MODAL", $modal->getHTML());
303 
305  $this->tpl->addOnLoadCode('longMenuQuestion.Init(' .
306  json_encode($long_menu_language) . ', ' .
307  json_encode($question_parts) . ', ' .
308  $answers . ');');
309  $button = new ilCustomInputGUI('&nbsp;', '');
310  $button->setHtml($tpl->get());
311  $form->addItem($button);
312  return $form;
313  }
314 
320  {
321  return $form;
322  }
323 
336  public function getSolutionOutput(
337  $active_id,
338  $pass = null,
339  $graphicalOutput = false,
340  $result_output = false,
341  $show_question_only = true,
342  $show_feedback = false,
343  $show_correct_solution = false,
344  $show_manual_scoring = false,
345  $show_question_text = true
346  ): string {
347 
348  if (($active_id > 0) && (!$show_correct_solution)) {
349  $user_solutions = $this->object->getSolutionValues($active_id, $pass, true);
350  } else {
351  $user_solutions = [];
352  foreach ($this->object->getCorrectAnswersForQuestionSolution($this->object->getId()) as $idx => $val) {
353  $user_solutions[] = [
354  'value1' => $idx,
355  'value2' => $val,
356  ];
357  }
358  }
359 
360  return $this->renderSolutionOutput(
361  $user_solutions,
362  $active_id,
363  $pass,
364  $graphicalOutput,
365  $result_output,
366  $show_question_only,
367  $show_feedback,
368  $show_correct_solution,
369  $show_manual_scoring,
370  $show_question_text,
371  false,
372  false
373  );
374  }
375 
376  public function renderSolutionOutput(
377  mixed $user_solutions,
378  int $active_id,
379  ?int $pass,
380  bool $graphical_output = false,
381  bool $result_output = false,
382  bool $show_question_only = true,
383  bool $show_feedback = false,
384  bool $show_correct_solution = false,
385  bool $show_manual_scoring = false,
386  bool $show_question_text = true,
387  bool $show_autosave_title = false,
388  bool $show_inline_feedback = false,
389  ): ?string {
390 
391  $user_solution = [];
392  foreach ($user_solutions as $idx => $solution_value) {
393  $user_solution[$solution_value['value1']] = $solution_value['value2'];
394  }
395 
396 
397  $template = new ilTemplate("tpl.il_as_qpl_longmenu_question_output_solution.html", true, true, "Modules/TestQuestionPool");
398  if ($show_question_text) {
399  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
400  }
401  $template->setVariable('LONGMENU_TEXT_SOLUTION', $this->getLongMenuTextWithInputFieldsInsteadOfGaps($user_solution, true, $graphical_output));
402  $solution_template = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
403  $question_output = $template->get();
404  $feedback = '';
405  if ($show_feedback) {
406  if (!$this->isTestPresentationContext()) {
407  $fb = $this->getGenericFeedbackOutput((int) $active_id, $pass);
408  $feedback .= strlen($fb) ? $fb : '';
409  }
410 
411  $fb = $this->getSpecificFeedbackOutput(array());
412  $feedback .= strlen($fb) ? $fb : '';
413  }
414  if (strlen($feedback)) {
415  $cssClass = (
416  $this->hasCorrectSolution($active_id, $pass) ?
418  );
419 
420  $solution_template->setVariable("ILC_FB_CSS_CLASS", $cssClass);
421  $solution_template->setVariable("FEEDBACK", ilLegacyFormElementsUtil::prepareTextareaOutput($feedback, true));
422  }
423 
424  $solution_template->setVariable("SOLUTION_OUTPUT", $question_output);
425 
426  $solution_output = $solution_template->get();
427 
428  if (!$show_question_only) {
429  $solution_output = $this->getILIASPage($solution_output);
430  }
431 
432  return $solution_output;
433  }
434 
435  public function getPreview($show_question_only = false, $showInlineFeedback = false): string
436  {
437  $user_solution = is_object($this->getPreviewSession()) ? (array) $this->getPreviewSession()->getParticipantsSolution() : array();
438  $user_solution = array_values($user_solution);
439 
440  $template = $this->getTemplateForPreviewAndTest($user_solution);
441 
442  $question_output = $template->get();
443  if (!$show_question_only) {
444  $question_output = $this->getILIASPage($question_output);
445  }
446  return $question_output;
447  }
448 
449  public function getTestOutput(
450  $active_id,
451  // hey: prevPassSolutions - will be always available from now on
452  $pass,
453  // hey.
454  $is_postponed = false,
455  $use_post_solutions = false,
456  $show_feedback = false
457  ): string {
458  $user_solution = [];
459  if ($active_id) {
460  $solutions = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
461  foreach ($solutions as $idx => $solution_value) {
462  $user_solution[$solution_value['value1']] = $solution_value['value2'];
463  }
464  }
465 
466  $template = $this->getTemplateForPreviewAndTest($user_solution);
467 
468  $question_output = $template->get();
469  $page_output = $this->outQuestionPage("", $is_postponed, $active_id, $question_output);
470  return $page_output;
471  }
472 
473  protected function getTemplateForPreviewAndTest(array $user_solution): ilTemplate
474  {
475  $template = new ilTemplate("tpl.il_as_qpl_longmenu_question_output.html", true, true, "Modules/TestQuestionPool");
476  $this->tpl->addJavaScript('./Modules/TestQuestionPool/templates/default/longMenuQuestionPlayer.js');
477  $this->tpl->addOnLoadCode('il.test.player.longmenu.init('
478  . $this->object->getMinAutoComplete() . ', '
479  . json_encode($this->object->getAvailableAnswerOptions())
480  . ')');
481 
482  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
483  $template->setVariable('LONGMENU_TEXT', $this->getLongMenuTextWithInputFieldsInsteadOfGaps($user_solution));
484  return $template;
485  }
486 
487  public function getSpecificFeedbackOutput(array $userSolution): string
488  {
489  if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
490  return '';
491  }
492 
493  $feedback = '<table class="test_specific_feedback"><tbody>';
494  $gaps = $this->object->getCorrectAnswers();
495  foreach ($gaps as $index => $answer) {
496  $caption = assLongMenu::GAP_PLACEHOLDER . ' ';
497  $caption .= $index + 1 . ': ';
498 
499  $feedback .= '<tr><td>';
500 
501  $feedback .= $caption . '</td><td>';
502  $feedback .= $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
503  $this->object->getId(),
504  0,
505  $index
506  ) . '</td> </tr>';
507  }
508  $feedback .= '</tbody></table>';
509  return ilLegacyFormElementsUtil::prepareTextareaOutput($feedback, true);
510  }
511 
512 
523  {
524  return array();
525  }
526 
533  public function getAggregatedAnswersView(array $relevant_answers): string
534  {
535  $overview = array();
536  $aggregation = array();
537  foreach ($relevant_answers as $answer) {
538  $overview[$answer['active_fi']][$answer['pass']][$answer['value1']] = $answer['value2'];
539  }
540 
541  foreach ($overview as $active) {
542  foreach ($active as $answer) {
543  foreach ($answer as $option => $value) {
544  $aggregation[$option][$value] = $aggregation[$option][$value] + 1;
545  }
546  }
547  }
548  $tpl = new ilTemplate('tpl.il_as_aggregated_longmenu_question_answers_table.html', true, true, "Modules/TestQuestionPool");
549  $json = json_decode($this->object->getJsonStructure());
550  foreach ($json as $key => $value) {
551  $tpl->setVariable('TITLE', 'Longmenu ' . ($key + 1));
552  if (array_key_exists($key, $aggregation)) {
553  $aggregate = $aggregation[$key];
554  foreach ($aggregate as $answer => $counts) {
555  $tpl->setVariable('OPTION', $answer);
556  $tpl->setVariable('COUNT', $counts);
558  }
559  }
560  }
561 
562  return $tpl->get();
563  }
564 
565  public function getLongMenuTextWithInputFieldsInsteadOfGaps($user_solution = [], $solution = false, $graphical = false): string
566  {
567  $return_value = '';
568  $text_array = preg_split("/\\[" . assLongMenu::GAP_PLACEHOLDER . " (\\d+)\\]/", $this->object->getLongMenuTextValue());
569  $correct_answers = $this->object->getCorrectAnswers();
570  $answers = $this->object->getAnswers();
571  foreach ($text_array as $key => $value) {
572  $answer_is_correct = false;
573  $user_value = '';
574  $return_value .= ilLegacyFormElementsUtil::prepareTextareaOutput($value, true);
575  if ($key < sizeof($text_array) - 1) {
576  if (!array_key_exists($key, $correct_answers)) {
577  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('longmenu_answeroptions_differ'));
578  continue;
579  }
580  if ($correct_answers[$key][2] == assLongMenu::ANSWER_TYPE_TEXT_VAL) {
581  if (array_key_exists($key, $user_solution)) {
582  $user_value = $user_solution[$key];
583  if (in_array($user_value, $correct_answers[$key][0])) {
584  $answer_is_correct = true;
585  }
586  }
587 
588  $return_value .= $this->getTextGapTemplate($key, $user_value, $solution, $answer_is_correct, $graphical);
589  } elseif ($correct_answers[$key][2] == assLongMenu::ANSWER_TYPE_SELECT_VAL) {
590  if (array_key_exists($key, $user_solution)) {
591  $user_value = $user_solution[$key];
592  if (in_array($user_value, $correct_answers[$key][0])) {
593  $answer_is_correct = true;
594  }
595  }
596  $return_value .= $this->getSelectGapTemplate($key, $answers[$key], $user_value, $solution, $answer_is_correct, $graphical);
597  }
598  }
599  }
600  return $return_value;
601  }
602 
603  private function getTextGapTemplate($key, $value, $solution, $ok = false, $graphical = false): string
604  {
605  $tpl = new ilTemplate("tpl.il_as_qpl_longmenu_question_text_gap.html", true, true, "Modules/TestQuestionPool");
606  if ($solution) {
607  $tpl->setVariable('DISABLED', 'disabled');
608  $tpl->setVariable('JS_IGNORE', '_ignore');
609  if ($graphical) {
610  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
611  if ($ok) {
612  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
613  }
614  $tpl->setVariable("ICON_OK", $correctness_icon);
615  }
616  }
617  if ($solution) {
618  $tpl->setVariable('SIZE', 'size="' . mb_strlen($value) . '"');
619  }
620  $tpl->setVariable('VALUE', htmlentities($value));
621  $tpl->setVariable('KEY', $key);
622 
623  return $tpl->get();
624  }
625 
626  private function getSelectGapTemplate($key, $answers, $user_value, $solution, $ok = false, $graphical = false): string
627  {
628  $tpl = new ilTemplate("tpl.il_as_qpl_longmenu_question_select_gap.html", true, true, "Modules/TestQuestionPool");
629  $tpl->setVariable('KEY', $key);
630  if ($solution) {
631  $tpl->setVariable('DISABLED', 'disabled');
632  $tpl->setVariable('JS_IGNORE', '_ignore');
633  $tpl->setCurrentBlock('best_solution');
634  if ($user_value == -1) {
635  $tpl->setVariable("SOLUTION", $this->lng->txt("please_select"));
636  } else {
637  $tpl->setVariable('SOLUTION', $user_value);
638  }
639  if ($graphical) {
640  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
641  if ($ok) {
642  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
643  }
644  $tpl->setVariable("ICON_OK", $correctness_icon);
645  }
647  } else {
648  $tpl->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
649  foreach ($answers as $value) {
650  $tpl->setCurrentBlock('select_option');
651  $tpl->setVariable('VALUE', $value);
652  if ($value == $user_value) {
653  $tpl->setVariable('SELECTED', 'selected');
654  }
656  }
657  }
658  return $tpl->get();
659  }
660 
661  public function getSubQuestionsIndex(): array
662  {
663  return array_keys($this->object->getAnswers());
664  }
665 
666  public function getAnswersFrequency($relevantAnswers, $questionIndex): array
667  {
668  $answers = [];
669 
670  foreach ($relevantAnswers as $row) {
671  if ($row['value1'] != $questionIndex) {
672  continue;
673  }
674 
675  if (!isset($answers[$row['value2']])) {
676  //$label = $this->getAnswerTextLabel($row['value1'], $row['value2']);
677 
678  $answers[$row['value2']] = array(
679  'answer' => $row['value2'], 'frequency' => 0
680  );
681  }
682 
683  $answers[$row['value2']]['frequency']++;
684  }
685 
686  return $answers;
687  }
688 
689  public function getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex): ilAnswerFrequencyStatisticTableGUI
690  {
691  global $DIC; /* @var ILIAS\DI\Container $DIC */
692 
693  $table = parent::getAnswerFrequencyTableGUI(
694  $parentGui,
695  $parentCmd,
696  $relevantAnswers,
697  $questionIndex
698  );
699 
700  $table->setTitle(
701  sprintf(
702  $DIC->language()->txt('tst_corrections_answers_tbl_subindex'),
703  $DIC->language()->txt('longmenu') . ' ' . ($questionIndex + 1)
704  )
705  );
706 
707  return $table;
708  }
709 
711  {
712  $correctAnswers = $this->object->getCorrectAnswers();
713 
714  foreach ($this->object->getAnswers() as $lmIndex => $lm) {
715  $lmValues = array(
716  'answers_all' => array(0 => $lm),
717  'answers_all_count' => count($lm),
718  'answers_correct' => $correctAnswers[$lmIndex][0]
719  );
720 
721  $lmPoints = $correctAnswers[$lmIndex][1];
722 
723  $section = new ilFormSectionHeaderGUI();
724  $section->setTitle($this->lng->txt('longmenu') . ' ' . ($lmIndex + 1));
725  $form->addItem($section);
726 
727  $lmInput = new ilAssLongmenuCorrectionsInputGUI(
728  $this->lng->txt('answers'),
729  'longmenu_' . $lmIndex
730  );
731 
732  $lmInput->setRequired(true);
733 
734  $lmInput->setValues($lmValues);
735 
736  $form->addItem($lmInput);
737 
738  $pointsInp = new ilNumberInputGUI($this->lng->txt("points"), 'points_' . $lmIndex);
739  $pointsInp->setRequired(true);
740  $pointsInp->allowDecimals(true);
741  $pointsInp->setSize(4);
742  $pointsInp->setMinValue(0);
743  $pointsInp->setMinvalueShouldBeGreater(false);
744  $pointsInp->setValue($lmPoints);
745  $form->addItem($pointsInp);
746  }
747  }
748 
753  {
754  $correctAnswers = $this->object->getCorrectAnswers();
755 
756  foreach ($this->object->getAnswers() as $lmIndex => $lm) {
757  $pointsInput = (float) str_replace(',', '.', $form->getInput('points_' . $lmIndex));
758  $correctAnswersInput = (array) $form->getInput('longmenu_' . $lmIndex . '_tags');
759 
760  foreach ($correctAnswersInput as $idx => $answer) {
761  if (in_array($answer, $lm)) {
762  continue;
763  }
764 
765  unset($correctAnswersInput[$idx]);
766  }
767 
768  $correctAnswersInput = array_values($correctAnswersInput);
769 
770  $correctAnswers[$lmIndex][0] = $correctAnswersInput;
771  $correctAnswers[$lmIndex][1] = $pointsInput;
772  }
773 
774  $this->object->setCorrectAnswers($correctAnswers);
775  }
776 }
static getSelfAssessmentTags()
Get tags allowed in question tags in self assessment mode.
getAnswersFrequency($relevantAnswers, $questionIndex)
hasCorrectSolution($activeId, $passIndex)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
generateCorrectnessIconsForCorrectness(int $correctness)
static stripSlashesRecursive($a_data, bool $a_strip_html=true, string $a_allow="")
setCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Sets the template to the given block.
getSelectGapTemplate($key, $answers, $user_value, $solution, $ok=false, $graphical=false)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
This is how a factory for glyphs looks like.
Definition: Factory.php:26
parseCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Parses the given block.
ilGlobalPageTemplate $tpl
populateTaxonomyFormSection(ilPropertyFormGUI $form)
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
global $DIC
Definition: feed.php:28
editQuestion(ilPropertyFormGUI $form=null)
getSpecificFeedbackOutput(array $userSolution)
const MIN_LENGTH_AUTOCOMPLETE
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const ANSWER_TYPE_TEXT_VAL
__construct(VocabulariesInterface $vocabularies)
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
trimArrayRecursive(array $data)
stripSlashesRecursive(array $data)
getLongMenuTextWithInputFieldsInsteadOfGaps($user_solution=[], $solution=false, $graphical=false)
writePostData(bool $always=false)
{}
string $key
Consumer key/client ID value.
Definition: System.php:193
getTestOutput( $active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
Basic GUI class for assessment questions.
setRequired(bool $a_required)
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
GlyphFactory $glyph_factory
static getInstance()
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
getTextGapTemplate($key, $value, $solution, $ok=false, $graphical=false)
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
This class represents a text area property in a property form.
const ADDITIONAL_CONTENT_EDITING_MODE_RTE
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$check
Definition: buildRTE.php:81
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
static prepareTextareaOutput(string $txt_output, bool $prepare_for_latex_output=false, bool $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
const ANSWER_TYPE_SELECT_VAL
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
setVariable(string $variable, $value='')
Sets the given variable to the given value.
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getPreview($show_question_only=false, $showInlineFeedback=false)
renderSolutionOutput(mixed $user_solutions, int $active_id, ?int $pass, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_autosave_title=false, bool $show_inline_feedback=false,)
getTemplateForPreviewAndTest(array $user_solution)
static _getUsedHTMLTags(string $a_module="")
Returns an array of all allowed HTML tags for text editing.
getGenericFeedbackOutput(int $active_id, ?int $pass)