ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.assOrderingQuestionGUI.php
Go to the documentation of this file.
1 <?php
2 
19 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
20 
37 {
38  public const CMD_EDIT_NESTING = 'editNesting';
39  public const CMD_SAVE_NESTING = 'saveNesting';
40  public const CMD_SWITCH_TO_TERMS = 'changeToText';
41  public const CMD_SWITCH_TO_PICTURESS = 'changeToPictures';
42 
43  public const TAB_EDIT_QUESTION = 'edit_question';
44  public const TAB_EDIT_NESTING = 'edit_nesting';
45 
46  public const F_USE_NESTED = 'nested_answers';
47  public const F_NESTED_ORDER = 'order_elems';
48  public const F_NESTED_ORDER_ORDER = 'content';
49  public const F_NESTED_ORDER_INDENT = 'indentation';
51 
53 
54  public $old_ordering_depth = [];
55  public $leveled_ordering = [];
56 
64  public function __construct($id = -1)
65  {
67  include_once "./Modules/TestQuestionPool/classes/class.assOrderingQuestion.php";
68  $this->object = new assOrderingQuestion();
69  if ($id >= 0) {
70  $this->object->loadFromDb($id);
71  }
72  }
73 
74  public function changeToPictures(): void
75  {
76  $this->object->setContentType($this->object::OQ_CT_PICTURES);
77  $this->object->saveToDb();
78 
79  $values = $this->request->getParsedBody();
80  $values['thumb_geometry'] = $this->object->getThumbSize();
81  $this->buildEditFormAfterTypeChange($values);
82  }
83 
84  public function changeToText(): void
85  {
86  $ordering_element_list = $this->object->getOrderingElementList();
87  foreach ($ordering_element_list as $element) {
88  $this->object->dropImageFile($element->getContent());
89  }
90 
91  $this->object->setContentType($this->object::OQ_CT_TERMS);
92  $this->object->saveToDb();
93 
94  $this->buildEditFormAfterTypeChange($this->request->getParsedBody());
95  }
96 
97  private function buildEditFormAfterTypeChange(array $values): void
98  {
99  $form = $this->buildEditForm();
100 
101  $ordering_element_list = $this->object->getOrderingElementList();
102  $ordering_element_list->resetElements();
103 
105  $form->setValuesByArray($values);
106  $form->getItemByPostVar(assOrderingQuestion::ORDERING_ELEMENT_FORM_FIELD_POSTVAR)->setElementList($ordering_element_list);
107  $this->renderEditForm($form);
108  $this->addEditSubtabs();
109  }
110 
111  public function saveNesting()
112  {
113  $form = $this->buildNestingForm();
114  $form->setValuesByPost();
115  if ($form->checkInput()) {
116  $post = $this->request->raw(self::F_NESTED_ORDER);
117  $list = $this->object->getOrderingElementList();
118 
119  $ordered = [];
120  foreach (array_keys($post[self::F_NESTED_ORDER_ORDER]) as $idx => $identifier) {
121  $element_identifier = str_replace(self::F_NESTED_IDENTIFIER_PREFIX, '', $identifier);
122  $element = $list->getElementByRandomIdentifier($element_identifier);
123 
124  $ordered[] = $element
125  ->withPosition($idx)
126  ->withIndentation($post[self::F_NESTED_ORDER_INDENT][$identifier]);
127  }
128 
129  $list = $list->withElements($ordered);
130  $this->object->setOrderingElementList($list);
131  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true);
132  } else {
133  $this->tpl->setOnScreenMessage('error', $this->lng->txt('form_input_not_valid'), true);
134  }
135 
136  $this->editNesting();
137  }
138 
139 
140  public function removeElementImage()
141  {
142  $this->uploadElementImage();
143  }
144 
145  public function uploadElementImage(): void
146  {
147  $form = $this->buildEditForm();
148  $form->setValuesByPost();
149 
150  $submitted_list = $this->fetchSolutionListFromSubmittedForm($form);
151 
152  $elements = [];
153  foreach ($submitted_list->getElements() as $submitted_element) {
154  if ($submitted_element->isImageUploadAvailable()) {
155  $filename = $this->object->storeImageFile(
156  $submitted_element->getUploadImageFile(),
157  $submitted_element->getUploadImageName()
158  );
159 
160  if (is_null($filename)) {
161  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('file_no_valid_file_type'));
162  } else {
163  $submitted_element = $submitted_element->withContent($filename);
164  }
165  }
166 
167  if ($submitted_element->isImageRemovalRequest()) {
168  $this->object->dropImageFile($submitted_element->getContent());
169  $submitted_element = $submitted_element->withContent('');
170  }
171 
172  $elements[] = $submitted_element;
173  }
174 
175  $list = $this->object->getOrderingElementList()->withElements($elements);
176  $this->object->setOrderingElementList($list);
177 
179  $this->writeQuestionSpecificPostData($form);
180 
181  $this->editQuestion();
182  }
183 
185  {
186  $thumb_size = $this->request->int('thumb_geometry');
187  if ($thumb_size !== 0
188  && $thumb_size !== $this->object->getThumbSize()) {
189  $this->object->setThumbSize($thumb_size);
190  $this->updateImageFiles();
191  }
192 
193  $points = (float) str_replace(',', '.', $this->request->raw('points'));
194 
195  $this->object->setPoints($points);
196 
197  $use_nested = $this->request->raw(self::F_USE_NESTED) === '1';
198  $this->object->setNestingType($use_nested);
199  }
200 
201 
203  {
205  ->getElementList($this->object->getId());
206 
207  $use_nested = $this->request->raw(self::F_USE_NESTED) === "1";
208 
209  if ($use_nested) {
210  $existing_list = $this->object->getOrderingElementList();
211 
212  $nu = [];
213  $parent_indent = -1;
214  foreach ($list->getElements() as $element) {
215  $element = $list->ensureValidIdentifiers($element);
216 
217  if ($existing = $existing_list->getElementByRandomIdentifier($element->getRandomIdentifier())) {
218  if ($existing->getIndentation() == $parent_indent + 1) {
219  $element = $element
220  ->withIndentation($existing->getIndentation());
221  }
222  }
223  $parent_indent = $element->getIndentation();
224  $nu[] = $element;
225  }
226  $list = $list->withElements($nu);
227  }
228 
229  return $list;
230  }
231 
232  protected function updateImageFiles(): void
233  {
234  $element_list = $this->object->getOrderingElementList();
235  $elements = [];
236  foreach ($element_list->getElements() as $element) {
237  if ($element->getContent() === '') {
238  continue;
239  }
240  $filename = $this->object->updateImageFile(
241  $element->getContent()
242  );
243 
244  $elements[] = $element->withContent($filename);
245  }
246 
247  $list = $this->object->getOrderingElementList()->withElements($elements);
248  $this->object->setOrderingElementList($list);
249  }
250 
251  public function writeAnswerSpecificPostData(ilPropertyFormGUI $form): void
252  {
253  $list = $this->fetchSolutionListFromSubmittedForm($form);
254  $this->object->setOrderingElementList($list);
255  return;
256  }
257 
259  {
260  $header = new ilFormSectionHeaderGUI();
261  $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
262  $form->addItem($header);
263 
264  $orderingElementInput = $this->object->buildOrderingElementInputGui();
265  $orderingElementInput->setStylingDisabled($this->isRenderPurposePrintPdf());
266  $this->object->initOrderingElementAuthoringProperties($orderingElementInput);
267 
268  $list = $this->object->getOrderingElementList();
269  $orderingElementInput->setElementList($list);
270  $form->addItem($orderingElementInput);
271 
272  return $form;
273  }
274 
276  {
277  if ($this->object->isImageOrderingType()) {
278  $thumb_size = new ilNumberInputGUI($this->lng->txt('thumb_size'), 'thumb_geometry');
279  $thumb_size->setValue($this->object->getThumbSize());
280  $thumb_size->setRequired(true);
281  $thumb_size->setMaxLength(6);
282  $thumb_size->setMinValue($this->object->getMinimumThumbSize());
283  $thumb_size->setMaxValue($this->object->getMaximumThumbSize());
284  $thumb_size->setSize(6);
285  $thumb_size->setInfo($this->lng->txt('thumb_size_info'));
286  $form->addItem($thumb_size);
287  }
288 
289  // points
290  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
291  $points->allowDecimals(true);
292  $points->setValue($this->object->getPoints());
293  $points->setRequired(true);
294  $points->setSize(3);
295  $points->setMinValue(0);
296  $points->setMinvalueShouldBeGreater(true);
297  $form->addItem($points);
298 
299  $nested_answers = new ilSelectInputGUI(
300  $this->lng->txt('qst_use_nested_answers'),
301  self::F_USE_NESTED
302  );
303  $nested_answers_options = [
304  0 => $this->lng->txt('qst_nested_nested_answers_off'),
305  1 => $this->lng->txt('qst_nested_nested_answers_on')
306  ];
307  $nested_answers->setOptions($nested_answers_options);
308  $nested_answers->setValue($this->object->isOrderingTypeNested());
309  $form->addItem($nested_answers);
310 
311  return $form;
312  }
313 
320  protected function writePostData(bool $always = false): int
321  {
322  $form = $this->buildEditForm();
323  $form->setValuesByPost();
324 
325  if (!$form->checkInput()) {
326  $this->renderEditForm($form);
327  $this->addEditSubtabs(self::TAB_EDIT_QUESTION);
328  return 1; // return 1 = something went wrong, no saving happened
329  }
330 
331  $this->saveTaxonomyAssignments();
333  $this->writeAnswerSpecificPostData($form);
334  $this->writeQuestionSpecificPostData($form);
335 
336  return 0; // return 0 = all fine, was saved either forced or validated
337  }
338 
339  protected function addEditSubtabs($active = self::TAB_EDIT_QUESTION)
340  {
341  $tabs = $this->getTabs();
342  $tabs->addSubTab(
343  self::TAB_EDIT_QUESTION,
344  $this->lng->txt('edit_question'),
345  $this->ctrl->getLinkTarget($this, 'editQuestion')
346  );
347  if ($this->object->isOrderingTypeNested()) {
348  $tabs->addSubTab(
349  self::TAB_EDIT_NESTING,
350  $this->lng->txt('tab_nest_answers'),
351  $this->ctrl->getLinkTarget($this, self::CMD_EDIT_NESTING)
352  );
353  }
354  $tabs->setTabActive('edit_question');
355  $tabs->setSubTabActive($active);
356  }
357 
358  public function editQuestion($checkonly = false): void
359  {
360  $this->renderEditForm($this->buildEditForm());
361  $this->addEditSubtabs(self::TAB_EDIT_QUESTION);
362  }
363 
364  public function editNesting()
365  {
366  $this->renderEditForm($this->buildNestingForm());
367  $this->addEditSubtabs(self::TAB_EDIT_NESTING);
368  $this->tpl->addCss(ilObjStyleSheet::getContentStylePath(0));
369  $this->tpl->addCss(ilObjStyleSheet::getSyntaxStylePath());
370  }
371 
373  {
374  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingQuestionAuthoringFormGUI.php';
376  $form->setFormAction($this->ctrl->getFormAction($this));
377  $form->setTitle($this->outQuestionType());
378  $form->setMultipart($this->object->isImageOrderingType());
379  $form->setTableWidth("100%");
380  $form->setId("ordering");
381 
382  $this->addBasicQuestionFormProperties($form);
383  $this->populateQuestionSpecificFormPart($form);
384  $this->populateAnswerSpecificFormPart($form);
385  $this->populateTaxonomyFormSection($form);
386 
387  $form->addSpecificOrderingQuestionCommandButtons($this->object);
388  $form->addGenericAssessmentQuestionCommandButtons($this->object);
389 
390  return $form;
391  }
392 
393  protected function buildNestingForm()
394  {
396  $form->setFormAction($this->ctrl->getFormAction($this));
397  $form->setTitle($this->outQuestionType());
398  $form->setTableWidth("100%");
399 
400  $header = new ilFormSectionHeaderGUI();
401  $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
402  $form->addItem($header);
403 
404  $orderingElementInput = $this->object->buildNestedOrderingElementInputGui();
405  $orderingElementInput->setStylingDisabled($this->isRenderPurposePrintPdf());
406 
407  $this->object->initOrderingElementAuthoringProperties($orderingElementInput);
408 
409  $list = $this->object->getOrderingElementList();
410  foreach ($list->getElements() as $element) {
411  $element = $list->ensureValidIdentifiers($element);
412  }
413 
414  $orderingElementInput->setElementList($list);
415 
416  $form->addItem($orderingElementInput);
417  $form->addCommandButton(self::CMD_SAVE_NESTING, $this->lng->txt("save"));
418  return $form;
419  }
420 
421 
428  {
429  return true;
430  }
431 
445  public function getSolutionOutput(
446  $active_id,
447  $pass = null,
448  $graphicalOutput = false,
449  $result_output = false,
450  $show_question_only = true,
451  $show_feedback = false,
452  $show_correct_solution = false,
453  $show_manual_scoring = false,
454  $show_question_text = true
455  ): string {
456  $solutionOrderingList = $this->object->getOrderingElementListForSolutionOutput(
457  $show_correct_solution,
458  $active_id,
459  $pass
460  );
461 
462  $answers_gui = $this->object->buildNestedOrderingElementInputGui();
463 
464  if ($show_correct_solution) {
466  } else {
468  }
469 
470  $answers_gui->setInteractionEnabled(false);
471  $answers_gui->setElementList($solutionOrderingList);
472  if ($graphicalOutput) {
473  $answers_gui->setShowCorrectnessIconsEnabled(true);
474  }
475  $answers_gui->setCorrectnessTrueElementList(
476  $solutionOrderingList->getParityTrueElementList($this->object->getOrderingElementList())
477  );
478  $solution_html = $answers_gui->getHTML();
479 
480  $template = new ilTemplate("tpl.il_as_qpl_nested_ordering_output_solution.html", true, true, "Modules/TestQuestionPool");
481  $template->setVariable('SOLUTION_OUTPUT', $solution_html);
482  if ($show_question_text == true) {
483  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
484  }
485  $questionoutput = $template->get();
486 
487  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
488  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
489 
490  if ($show_feedback) {
491  $feedback = '';
492 
493  if (!$this->isTestPresentationContext()) {
494  $fb = $this->getGenericFeedbackOutput((int) $active_id, $pass);
495  $feedback .= strlen($fb) ? $fb : '';
496  }
497 
498  if (strlen($feedback)) {
499  $cssClass = (
500  $this->hasCorrectSolution($active_id, $pass) ?
502  );
503 
504  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
505  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
506  }
507  }
508 
509  if ($show_question_only) {
510  return $solutiontemplate->get();
511  }
512 
513  return $this->getILIASPage($solutiontemplate->get());
514 
515  // is this template still in use? it is not used at this point any longer!
516  // $template = new ilTemplate("tpl.il_as_qpl_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
517  }
518 
519  public function getPreview($show_question_only = false, $showInlineFeedback = false): string
520  {
521  if ($this->getPreviewSession() && $this->getPreviewSession()->hasParticipantSolution()) {
522  $solutionOrderingElementList = unserialize(
523  $this->getPreviewSession()->getParticipantsSolution(),
524  ["allowed_classes" => true]
525  );
526  } else {
527  $solutionOrderingElementList = $this->object->getShuffledOrderingElementList();
528  }
529 
530  $answers = $this->object->buildNestedOrderingElementInputGui();
531  $answers->setNestingEnabled($this->object->isOrderingTypeNested());
533  $answers->setInteractionEnabled($this->isInteractivePresentation());
534  $answers->setElementList($solutionOrderingElementList);
535 
536  $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", true, true, "Modules/TestQuestionPool");
537 
538  $template->setCurrentBlock('nested_ordering_output');
539  $template->setVariable('NESTED_ORDERING', $answers->getHTML());
540  $template->parseCurrentBlock();
541 
542  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
543 
544  if ($show_question_only) {
545  return $template->get();
546  }
547 
548  return $this->getILIASPage($template->get());
549  }
550 
551  public function getPresentationJavascripts(): array
552  {
553  global $DIC; /* @var ILIAS\DI\Container $DIC */
554 
555  $files = [];
556 
557  if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
558  $files[] = './node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js';
559  }
560 
561  return $files;
562  }
563 
564  // hey: prevPassSolutions - pass will be always available from now on
565  public function getTestOutput($activeId, $pass, $isPostponed = false, $userSolutionPost = false, $inlineFeedback = false): string
566  // hey.
567  {
568  // hey: prevPassSolutions - fixed variable type, makes phpstorm stop crying
569  $userSolutionPost = is_array($userSolutionPost) ? $userSolutionPost : array();
570  // hey.
571 
572  $orderingGUI = $this->object->buildNestedOrderingElementInputGui();
573  $orderingGUI->setNestingEnabled($this->object->isOrderingTypeNested());
574 
575  $solutionOrderingElementList = $this->object->getSolutionOrderingElementListForTestOutput(
576  $orderingGUI,
577  $userSolutionPost,
578  $activeId,
579  $pass
580  );
581 
582  $template = new ilTemplate('tpl.il_as_qpl_ordering_output.html', true, true, 'Modules/TestQuestionPool');
583 
585  $orderingGUI->setElementList($solutionOrderingElementList);
586 
587  $template->setCurrentBlock('nested_ordering_output');
588  $template->setVariable('NESTED_ORDERING', $orderingGUI->getHTML());
589  $template->parseCurrentBlock();
590 
591  $template->setVariable('QUESTIONTEXT', $this->object->getQuestionForHTMLOutput());
592 
593  $pageoutput = $this->outQuestionPage('', $isPostponed, $activeId, $template->get());
594 
595  return $pageoutput;
596  }
597 
598  protected function isInteractivePresentation(): bool
599  {
600  if ($this->isRenderPurposePlayback()) {
601  return true;
602  }
603 
604  if ($this->isRenderPurposeDemoplay()) {
605  return true;
606  }
607 
608  return false;
609  }
610 
611  protected function getTabs(): ilTabsGUI
612  {
613  global $DIC;
614  return $DIC['ilTabs'];
615  }
616 
617  public function getSpecificFeedbackOutput(array $userSolution): string
618  {
619  return '';
620  }
621 
632  {
633  return array();
634  }
635 
646  {
647  return array();
648  }
649 
656  public function getAggregatedAnswersView(array $relevant_answers): string
657  {
658  $aggView = $this->aggregateAnswers(
659  $relevant_answers,
660  $this->object->getOrderingElementList()
661  );
662 
663  return $this->renderAggregateView($aggView)->get();
664  }
665 
666  public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question): array
667  {
668  $passdata = array(); // Regroup answers into units of passes.
669  foreach ($relevant_answers_chosen as $answer_chosen) {
670  $passdata[$answer_chosen['active_fi'] . '-' . $answer_chosen['pass']][$answer_chosen['value2']] = $answer_chosen['value1'];
671  }
672 
673  $variants = array(); // Determine unique variants.
674  foreach ($passdata as $key => $data) {
675  $hash = md5(implode('-', $data));
676  $value_set = false;
677  foreach ($variants as $vkey => $variant) {
678  if ($variant['hash'] == $hash) {
679  $variant['count']++;
680  $value_set = true;
681  }
682  }
683  if (!$value_set) {
684  $variants[$key]['hash'] = $hash;
685  $variants[$key]['count'] = 1;
686  }
687  }
688 
689  $aggregate = array(); // Render aggregate from variant.
690  foreach ($variants as $key => $variant_entry) {
691  $variant = $passdata[$key];
692 
693  foreach ($variant as $variant_key => $variant_line) {
694  $i = 0;
695  $aggregated_info_for_answer['count'] = $variant_entry['count'];
696  foreach ($answers_defined_on_question as $element) {
697  $i++;
698 
699  if ($this->object->isImageOrderingType()) {
700  $element->setImageThumbnailPrefix($this->object->getThumbPrefix());
701  $element->setImagePathWeb($this->object->getImagePathWeb());
702  $element->setImagePathFs($this->object->getImagePath());
703 
704  $src = $element->getPresentationImageUrl();
705  $alt = $element->getContent();
706  $content = "<img src='{$src}' alt='{$alt}' title='{$alt}'/>";
707  } else {
708  $content = $element->getContent();
709  }
710 
711  $aggregated_info_for_answer[$i . ' - ' . $content]
712  = $passdata[$key][$i];
713  }
714  }
715  $aggregate[] = $aggregated_info_for_answer;
716  }
717  return $aggregate;
718  }
719 
725  public function renderAggregateView($aggregate): ilTemplate
726  {
727  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
728 
729  foreach ($aggregate as $line_data) {
730  $tpl->setCurrentBlock('aggregaterow');
731  $count = array_shift($line_data);
732  $html = '<ul>';
733  foreach ($line_data as $key => $line) {
734  $html .= '<li>' . ++$line . '&nbsp;-&nbsp;' . $key . '</li>';
735  }
736  $html .= '</ul>';
737  $tpl->setVariable('COUNT', $count);
738  $tpl->setVariable('OPTION', $html);
739 
741  }
742  return $tpl;
743  }
744 
745  protected function getAnswerStatisticOrderingElementHtml(ilAssOrderingElement $element): ?string
746  {
747  if ($this->object->isImageOrderingType()) {
748  $element->setImageThumbnailPrefix($this->object->getThumbPrefix());
749  $element->setImagePathWeb($this->object->getImagePathWeb());
750  $element->setImagePathFs($this->object->getImagePath());
751 
752  $src = $element->getPresentationImageUrl();
753  $alt = $element->getContent();
754  $content = "<img src='{$src}' alt='{$alt}' title='{$alt}'/>";
755  } else {
756  $content = $element->getContent();
757  }
758 
759  return $content;
760  }
761 
763  {
764  $html = '<ul>';
765 
766  $lastIndent = 0;
767  $firstElem = true;
768 
769  foreach ($list as $elem) {
770  if ($elem->getIndentation() > $lastIndent) {
771  $html .= '<ul><li>';
772  } elseif ($elem->getIndentation() < $lastIndent) {
773  $html .= '</li></ul><li>';
774  } elseif (!$firstElem) {
775  $html .= '</li><li>';
776  } else {
777  $html .= '<li>';
778  }
779 
780  $html .= $this->getAnswerStatisticOrderingElementHtml($elem);
781 
782  $firstElem = false;
783  $lastIndent = $elem->getIndentation();
784  }
785 
786  $html .= '</li>';
787 
788  for ($i = $lastIndent; $i > 0; $i--) {
789  $html .= '</ul></li>';
790  }
791 
792  $html .= '</ul>';
793 
794  return $html;
795  }
796 
797  public function getAnswersFrequency($relevantAnswers, $questionIndex): array
798  {
799  $answersByActiveAndPass = array();
800 
801  foreach ($relevantAnswers as $row) {
802  $key = $row['active_fi'] . ':' . $row['pass'];
803 
804  if (!isset($answersByActiveAndPass[$key])) {
805  $answersByActiveAndPass[$key] = array();
806  }
807 
808  $answersByActiveAndPass[$key][$row['value1']] = $row['value2'];
809  }
810 
811  $solutionLists = array();
812 
813  foreach ($answersByActiveAndPass as $indexedSolutions) {
814  $solutionLists[] = $this->object->getSolutionOrderingElementList($indexedSolutions);
815  }
816 
817  /* @var ilAssOrderingElementList[] $answers */
818  $answers = array();
819 
820  foreach ($solutionLists as $orderingElementList) {
821  $hash = $orderingElementList->getHash();
822 
823  if (!isset($answers[$hash])) {
824  $variantHtml = $this->getAnswerStatisticOrderingVariantHtml(
825  $orderingElementList
826  );
827 
828  $answers[$hash] = array(
829  'answer' => $variantHtml, 'frequency' => 0
830  );
831  }
832 
833  $answers[$hash]['frequency']++;
834  }
835 
836  return array_values($answers);
837  }
838 
843  {
845  $orderingInput->prepareReprintable($this->object);
846  }
847 
852  {
853  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
854  $points->allowDecimals(true);
855  $points->setValue($this->object->getPoints());
856  $points->setRequired(true);
857  $points->setSize(3);
858  $points->setMinValue(0);
859  $points->setMinvalueShouldBeGreater(true);
860  $form->addItem($points);
861 
862  $header = new ilFormSectionHeaderGUI();
863  $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
864  $form->addItem($header);
865 
866  $orderingElementInput = $this->object->buildNestedOrderingElementInputGui();
867 
868  $this->object->initOrderingElementAuthoringProperties($orderingElementInput);
869 
870  $orderingElementInput->setElementList($this->object->getOrderingElementList());
871 
872  $form->addItem($orderingElementInput);
873  }
874 
879  {
880  $this->object->setPoints((float) str_replace(',', '.', $form->getInput('points')));
881 
882  $submittedElementList = $this->fetchSolutionListFromSubmittedForm($form);
883 
884  $curElementList = $this->object->getOrderingElementList();
885 
886  $newElementList = new ilAssOrderingElementList();
887  $newElementList->setQuestionId($this->object->getId());
888 
889  foreach ($submittedElementList as $submittedElement) {
890  if (!$curElementList->elementExistByRandomIdentifier($submittedElement->getRandomIdentifier())) {
891  continue;
892  }
893 
894  $curElement = $curElementList->getElementByRandomIdentifier($submittedElement->getRandomIdentifier());
895 
896  $curElement->setPosition($submittedElement->getPosition());
897 
898  if ($this->object->isOrderingTypeNested()) {
899  $curElement->setIndentation($submittedElement->getIndentation());
900  }
901 
902  $newElementList->addElement($curElement);
903  }
904 
905  $this->object->setOrderingElementList($newElementList);
906  }
907 }
__construct($id=-1)
assOrderingQuestionGUI constructor
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
hasCorrectSolution($activeId, $passIndex)
getSpecificFeedbackOutput(array $userSolution)
prepareReprintableCorrectionsForm(ilPropertyFormGUI $form)
setCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Sets the template to the given block.
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAnswerStatisticOrderingVariantHtml(ilAssOrderingElementList $list)
getItemByPostVar(string $a_post_var)
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
Adds the answer specific form parts to a question property form gui.
Abstract basic class which is to be extended by the concrete assessment question type classes...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
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.
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
parseCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Parses the given block.
writePostData(bool $always=false)
{}
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-...
global $DIC
Definition: feed.php:28
allowDecimals(bool $a_value)
fetchSolutionListFromSubmittedForm(ilPropertyFormGUI $form)
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
This class represents a number property in a property form.
setValue(?string $a_value)
getTestOutput($activeId, $pass, $isPostponed=false, $userSolutionPost=false, $inlineFeedback=false)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
addEditSubtabs($active=self::TAB_EDIT_QUESTION)
string $key
Consumer key/client ID value.
Definition: System.php:193
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
$filename
Definition: buildRTE.php:78
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
setImageThumbnailPrefix($imageThumbnailPrefix)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
__construct(Container $dic, ilPlugin $plugin)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPreview($show_question_only=false, $showInlineFeedback=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAnswersFrequency($relevantAnswers, $questionIndex)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$post
Definition: ltitoken.php:49
getAnswerStatisticOrderingElementHtml(ilAssOrderingElement $element)
setVariable(string $variable, $value='')
Sets the given variable to the given value.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
$i
Definition: metadata.php:41
renderEditForm(ilPropertyFormGUI $form)
getGenericFeedbackOutput(int $active_id, ?int $pass)