ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assOrderingQuestionGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7require_once './Modules/Test/classes/inc.AssessmentConstants.php';
8
24{
28 public $object;
29
30 public $old_ordering_depth = array();
31 public $leveled_ordering = array();
32
37
47 public function __construct($id = -1)
48 {
49 parent::__construct();
50 include_once "./Modules/TestQuestionPool/classes/class.assOrderingQuestion.php";
51 $this->object = new assOrderingQuestion();
52 if ($id >= 0) {
53 $this->object->loadFromDb($id);
54 }
55 $this->clearAnswersOnWritingPostDataEnabled = false;
56 }
57
62 {
63 $this->clearAnswersOnWritingPostDataEnabled = $clearAnswersOnWritingPostDataEnabled;
64 }
65
70 {
72 }
73
74 public function changeToPictures()
75 {
76 if ($this->object->getOrderingType() != OQ_NESTED_PICTURES && $this->object->getOrderingType() != OQ_PICTURES) {
78 }
79
80 $form = $this->buildEditForm();
81 $form->setValuesByPost();
83
84 $this->object->setOrderingType(OQ_PICTURES);
85 $this->object->saveToDb();
86
87 $form->ensureReprintableFormStructure($this->object);
88 $this->renderEditForm($form);
89 }
90
91 public function changeToText()
92 {
93 if ($this->object->getOrderingType() != OQ_NESTED_TERMS && $this->object->getOrderingType() != OQ_TERMS) {
95 }
96
97 $form = $this->buildEditForm();
98 $form->setValuesByPost();
100
101 $this->object->setOrderingType(OQ_TERMS);
102 $this->object->saveToDb();
103
104 $form->ensureReprintableFormStructure($this->object);
105 $this->renderEditForm($form);
106 }
107
108 public function orderNestedTerms()
109 {
110 $this->writePostData(true);
111 $this->object->setOrderingType(OQ_NESTED_TERMS);
112 $this->object->saveToDb();
113
114 $this->renderEditForm($this->buildEditForm());
115 }
116
117 public function orderNestedPictures()
118 {
119 $this->writePostData(true);
120 $this->object->setOrderingType(OQ_NESTED_PICTURES);
121 $this->object->saveToDb();
122
123 $this->renderEditForm($this->buildEditForm());
124 }
125
126 public function removeElementImage()
127 {
128 $orderingInput = $this->object->buildOrderingImagesInputGui();
129 $this->object->initOrderingElementAuthoringProperties($orderingInput);
130
131 $form = $this->buildEditForm();
132 $form->replaceFormItemByPostVar($orderingInput);
133 $form->setValuesByPost();
134
135 $replacementElemList = ilAssOrderingElementList::buildInstance(
136 $this->object->getId(),
137 array()
138 );
139
140 $storedElementList = $this->object->getOrderingElementList();
141
142 foreach ($orderingInput->getElementList($this->object->getId()) as $submittedElement) {
143 if ($submittedElement->isImageRemovalRequest()) {
144 if ($this->object->isImageFileStored($submittedElement->getContent())) {
145 $this->object->dropImageFile($submittedElement->getContent());
146 }
147
148 $submittedElement->setContent(null);
149 }
150
151 if ($storedElementList->elementExistByRandomIdentifier($submittedElement->getRandomIdentifier())) {
152 $storedElement = $storedElementList->getElementByRandomIdentifier(
153 $submittedElement->getRandomIdentifier()
154 );
155
156 $submittedElement->setSolutionIdentifier($storedElement->getSolutionIdentifier());
157 $submittedElement->setIndentation($storedElement->getIndentation());
158 }
159
160 $replacementElemList->addElement($submittedElement);
161 }
162
163 $replacementElemList->saveToDb();
164
165 $orderingInput->setElementList($replacementElemList);
166 $this->renderEditForm($form);
167 }
168
169 public function uploadElementImage()
170 {
171 $orderingInput = $this->object->buildOrderingImagesInputGui();
172 $this->object->initOrderingElementAuthoringProperties($orderingInput);
173
174 $form = $this->buildEditForm();
175 $form->replaceFormItemByPostVar($orderingInput);
176 $form->setValuesByPost();
177
178 if (!$orderingInput->checkInput()) {
179 ilUtil::sendFailure($this->lng->txt('form_input_not_valid'));
180 }
181
183 $this->object->getOrderingElementList()->saveToDb();
184 $orderingInput->setElementList($this->object->getOrderingElementList());
185
186 $this->renderEditForm($form);
187 }
188
190 {
191 $this->object->setThumbGeometry($_POST["thumb_geometry"]);
192 $this->object->setElementHeight($_POST["element_height"]);
193 //$this->object->setOrderingType( $_POST["ordering_type"] );
194 $this->object->setPoints($_POST["points"]);
195 }
196
198 {
200 throw new ilTestQuestionPoolException('form submit request missing the form submit!?');
201 }
202
203 #$submittedElementList = $this->object->fetchSolutionListFromFormSubmissionData($_POST);
204 $submittedElementList = $this->object->fetchSolutionListFromSubmittedForm($form);
205
206 $replacementElementList = new ilAssOrderingElementList();
207 $replacementElementList->setQuestionId($this->object->getId());
208
209 $currentElementList = $this->object->getOrderingElementList();
210
211 foreach ($submittedElementList as $submittedElement) {
212 if ($this->object->hasOrderingTypeUploadSupport()) {
213 if ($submittedElement->isImageUploadAvailable()) {
214 $suffix = strtolower(array_pop(explode(".", $submittedElement->getUploadImageName())));
215 if (in_array($suffix, array("jpg", "jpeg", "png", "gif"))) {
216 $submittedElement->setUploadImageName($this->object->buildHashedImageFilename(
217 $submittedElement->getUploadImageName(),
218 true
219 ));
220
221 $wasImageFileStored = $this->object->storeImageFile(
222 $submittedElement->getUploadImageFile(),
223 $submittedElement->getUploadImageName()
224 );
225
226 if ($wasImageFileStored) {
227 if ($this->object->isImageFileStored($submittedElement->getContent())) {
228 $this->object->dropImageFile($submittedElement->getContent());
229 }
230
231 $submittedElement->setContent($submittedElement->getUploadImageName());
232 }
233 }
234 }
235 }
236
237 if ($currentElementList->elementExistByRandomIdentifier($submittedElement->getRandomIdentifier())) {
238 $storedElement = $currentElementList->getElementByRandomIdentifier(
239 $submittedElement->getRandomIdentifier()
240 );
241
242 $submittedElement->setSolutionIdentifier($storedElement->getSolutionIdentifier());
243
244 if ($this->isAdjustmentEditContext() || $this->object->isOrderingTypeNested()) {
245 $submittedElement->setContent($storedElement->getContent());
246 }
247
248 if (!$this->object->isOrderingTypeNested()) {
249 $submittedElement->setIndentation($storedElement->getIndentation());
250 }
251
252 if ($this->object->isImageReplaced($submittedElement, $storedElement)) {
253 $this->object->dropImageFile($storedElement->getContent());
254 }
255 }
256
257 $replacementElementList->addElement($submittedElement);
258 }
259
260 if ($this->object->isImageOrderingType()) {
261 $this->object->handleThumbnailCreation($replacementElementList);
262 }
263
265 $replacementElementList->clearElementContents();
266 }
267
268 if ($this->object->hasOrderingTypeUploadSupport()) {
269 $obsoleteElementList = $currentElementList->getDifferenceElementList($replacementElementList);
270
271 foreach ($obsoleteElementList as $obsoleteElement) {
272 $this->object->dropImageFile($obsoleteElement->getContent());
273 }
274 }
275
276 $this->object->setOrderingElementList($replacementElementList);
277 }
278
280 {
282 $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
283 $form->addItem($header);
284
285 if ($this->isAdjustmentEditContext()) {
286 $orderingElementInput = $this->object->buildNestedOrderingElementInputGui();
287 } else {
288 $orderingElementInput = $this->object->buildOrderingElementInputGui();
289 }
290
291 $orderingElementInput->setStylingDisabled($this->isRenderPurposePrintPdf());
292 $this->object->initOrderingElementAuthoringProperties($orderingElementInput);
293
294 $orderingElementInput->setElementList($this->object->getOrderingElementList());
295
296 $form->addItem($orderingElementInput);
297
298 return $form;
299 }
300
302 {
303 if (!$this->object->getSelfAssessmentEditingMode()) {
304 $element_height = new ilNumberInputGUI($this->lng->txt("element_height"), "element_height");
305 $element_height->setValue($this->object->getElementHeight());
306 $element_height->setRequired(false);
307 $element_height->setMaxLength(6);
308 $element_height->setMinValue(20);
309 $element_height->setSize(6);
310 $element_height->setInfo($this->lng->txt("element_height_info"));
311 $form->addItem($element_height);
312 }
313
314 if ($this->object->isImageOrderingType()) {
315 $geometry = new ilNumberInputGUI($this->lng->txt("thumb_geometry"), "thumb_geometry");
316 $geometry->setValue($this->object->getThumbGeometry());
317 $geometry->setRequired(true);
318 $geometry->setMaxLength(6);
319 $geometry->setMinValue(20);
320 $geometry->setSize(6);
321 $geometry->setInfo($this->lng->txt("thumb_geometry_info"));
322 $form->addItem($geometry);
323 }
324
325 // points
326 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
327 $points->allowDecimals(true);
328 $points->setValue($this->object->getPoints());
329 $points->setRequired(true);
330 $points->setSize(3);
331 $points->setMinValue(0);
332 $points->setMinvalueShouldBeGreater(true);
333 $form->addItem($points);
334
335 return $form;
336 }
337
341 protected function writePostData($forceSaving = false)
342 {
343 $savingAllowed = true; // assume saving allowed first
344
345 if (!$forceSaving) {
346 // this case seems to be a regular save call, so we consider
347 // the validation result for the decision of saving as well
348
349 // inits {this->editForm} and performs validation
350 $form = $this->buildEditForm();
351 $form->setValuesByPost(); // manipulation and distribution of values
352
353 if (!$form->checkInput()) { // manipulations regular style input propeties
354 $form->prepareValuesReprintable($this->object);
355 $this->renderEditForm($form);
356
357 // consequence of vaidation
358 $savingAllowed = false;
359 }
360 } elseif (!$this->isSaveCommand()) {
361 // this case handles form workflow actions like the mode/view switching requests,
362 // so saving must not be skipped, even for inputs invalid by business rules
363
364 $form = $this->buildEditForm();
365 $form->setValuesByPost(); // manipulation and distribution of values
366 $form->checkInput(); // manipulations regular style input propeties
367 }
368
369 if ($savingAllowed) {
371
372 return 0; // return 0 = all fine, was saved either forced or validated
373 }
374
375 return 1; // return 1 = something went wrong, no saving happened
376 }
377
381 public function editQuestion($checkonly = false)
382 {
383 $this->renderEditForm($this->buildEditForm());
384 }
385
389 protected function buildEditForm()
390 {
391 require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingQuestionAuthoringFormGUI.php';
393 $this->editForm = $form;
394
395 $form->setFormAction($this->ctrl->getFormAction($this));
396 $form->setTitle($this->outQuestionType());
397 $form->setMultipart(($this->object->getOrderingType() == OQ_PICTURES) ? true : false);
398 $form->setTableWidth("100%");
399 $form->setId("ordering");
400 // title, author, description, question, working time (assessment mode)
404
406
407 $form->addSpecificOrderingQuestionCommandButtons($this->object);
408 $form->addGenericAssessmentQuestionCommandButtons($this->object);
409
410 return $form;
411 }
412
419 {
420 return true;
421 }
422
438 public function getSolutionOutput(
439 $active_id,
440 $pass = null,
441 $graphicalOutput = false,
442 $result_output = false,
443 $show_question_only = true,
444 $show_feedback = false,
445 $forceCorrectSolution = false,
446 $show_manual_scoring = false,
447 $show_question_text = true
448 ) {
449 $solutionOrderingList = $this->object->getOrderingElementListForSolutionOutput(
450 $forceCorrectSolution,
451 $active_id,
452 $pass,
454 );
455
456 $answers_gui = $this->object->buildNestedOrderingElementInputGui();
457
458 if ($forceCorrectSolution) {
460 } else {
462 }
463
464 $answers_gui->setInteractionEnabled(false);
465
466 $answers_gui->setElementList($solutionOrderingList);
467
468 $answers_gui->setCorrectnessTrueElementList(
469 $solutionOrderingList->getParityTrueElementList($this->object->getOrderingElementList())
470 );
471
472 $solution_html = $answers_gui->getHTML();
473
474 $template = new ilTemplate("tpl.il_as_qpl_nested_ordering_output_solution.html", true, true, "Modules/TestQuestionPool");
475 $template->setVariable('SOLUTION_OUTPUT', $solution_html);
476 if ($show_question_text == true) {
477 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
478 }
479 $questionoutput = $template->get();
480
481 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
482 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
483
484 if ($show_feedback) {
485 $feedback = '';
486
487 if (!$this->isTestPresentationContext()) {
488 $fb = $this->getGenericFeedbackOutput($active_id, $pass);
489 $feedback .= strlen($fb) ? $fb : '';
490 }
491
492 $fb = $this->getSpecificFeedbackOutput(array());
493 $feedback .= strlen($fb) ? $fb : '';
494
495 if (strlen($feedback)) {
496 $cssClass = (
497 $this->hasCorrectSolution($active_id, $pass) ?
499 );
500
501 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
502 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
503 }
504 }
505
506 if ($show_question_only) {
507 return $solutiontemplate->get();
508 }
509
510 return $this->getILIASPage($solutiontemplate->get());
511
512 // is this template still in use? it is not used at this point any longer!
513 // $template = new ilTemplate("tpl.il_as_qpl_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
514 }
515
516 public function getPreview($show_question_only = false, $showInlineFeedback = false)
517 {
518 if ($this->getPreviewSession() && $this->getPreviewSession()->hasParticipantSolution()) {
519 $solutionOrderingElementList = unserialize(
520 $this->getPreviewSession()->getParticipantsSolution()
521 );
522 } else {
523 $solutionOrderingElementList = $this->object->getShuffledOrderingElementList();
524 }
525
526 $answers = $this->object->buildNestedOrderingElementInputGui();
527 $answers->setNestingEnabled($this->object->isOrderingTypeNested());
529 $answers->setInteractionEnabled($this->isInteractivePresentation());
530 $answers->setElementList($solutionOrderingElementList);
531
532 $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", true, true, "Modules/TestQuestionPool");
533
534 $template->setCurrentBlock('nested_ordering_output');
535 $template->setVariable('NESTED_ORDERING', $answers->getHTML());
536 $template->parseCurrentBlock();
537
538 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
539
540 if ($show_question_only) {
541 return $template->get();
542 }
543
544 return $this->getILIASPage($template->get());
545
546 //$this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/ordering.js");
547 }
548
549 // hey: prevPassSolutions - pass will be always available from now on
550 public function getTestOutput($activeId, $pass, $isPostponed = false, $userSolutionPost = false, $inlineFeedback = false)
551 // hey.
552 {
553 // hey: prevPassSolutions - fixed variable type, makes phpstorm stop crying
554 $userSolutionPost = is_array($userSolutionPost) ? $userSolutionPost : array();
555 // hey.
556
557 $orderingGUI = $this->object->buildNestedOrderingElementInputGui();
558 $orderingGUI->setNestingEnabled($this->object->isOrderingTypeNested());
559
560 $solutionOrderingElementList = $this->object->getSolutionOrderingElementListForTestOutput(
561 $orderingGUI,
562 $userSolutionPost,
563 $activeId,
564 $pass
565 );
566
567 $template = new ilTemplate('tpl.il_as_qpl_ordering_output.html', true, true, 'Modules/TestQuestionPool');
568
570 $orderingGUI->setElementList($solutionOrderingElementList);
571
572 $template->setCurrentBlock('nested_ordering_output');
573 $template->setVariable('NESTED_ORDERING', $orderingGUI->getHTML());
574 $template->parseCurrentBlock();
575
576 $template->setVariable('QUESTIONTEXT', $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
577
578 $pageoutput = $this->outQuestionPage('', $isPostponed, $activeId, $template->get());
579
580 return $pageoutput;
581 }
582
583 protected function isInteractivePresentation()
584 {
585 if ($this->isRenderPurposePlayback()) {
586 return true;
587 }
588
589 if ($this->isRenderPurposeDemoplay()) {
590 return true;
591 }
592
593 return false;
594 }
595
603 public function setQuestionTabs()
604 {
605 global $DIC;
606 $rbacsystem = $DIC['rbacsystem'];
607 $ilTabs = $DIC['ilTabs'];
608
609 $ilTabs->clearTargets();
610
611 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
612 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
613 $q_type = $this->object->getQuestionType();
614
615 if (strlen($q_type)) {
616 $classname = $q_type . "GUI";
617 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
618 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
619 }
620
621 if ($_GET["q_id"]) {
622 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
623 // edit page
624 $ilTabs->addTarget(
625 "edit_page",
626 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
627 array("edit", "insert", "exec_pg"),
628 "",
629 "",
630 false
631 );
632 }
633
634 $this->addTab_QuestionPreview($ilTabs);
635 }
636
637 $force_active = false;
638 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
639 $url = "";
640 if ($classname) {
641 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
642 }
643 $commands = $_POST["cmd"];
644 if (is_array($commands)) {
645 foreach ($commands as $key => $value) {
646 if (preg_match("/^delete_.*/", $key, $matches)) {
647 $force_active = true;
648 }
649 }
650 }
651 // edit question properties
652 $ilTabs->addTarget(
653 "edit_question",
654 $url,
655 array("orderNestedTerms","orderNestedPictures","editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "changeToPictures", "uploadElementImage", "changeToText", "upanswers", "downanswers", "originalSyncForm"),
656 $classname,
657 "",
658 $force_active
659 );
660 }
661
662 // add tab for question feedback within common class assQuestionGUI
663 $this->addTab_QuestionFeedback($ilTabs);
664
665 // add tab for question hint within common class assQuestionGUI
666 $this->addTab_QuestionHints($ilTabs);
667
668 // add tab for question's suggested solution within common class assQuestionGUI
669 $this->addTab_SuggestedSolution($ilTabs, $classname);
670
671 // Assessment of questions sub menu entry
672 if ($_GET["q_id"]) {
673 $ilTabs->addTarget(
674 "statistics",
675 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
676 array("assessment"),
677 $classname,
678 ""
679 );
680 }
681
682 $this->addBackTab($ilTabs);
683 }
684
685 public function getSpecificFeedbackOutput($userSolution)
686 {
687 if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
688 return '';
689 }
690
691 $tpl = new ilTemplate('tpl.il_as_qpl_ordering_elem_fb.html', true, true, 'Modules/TestQuestionPool');
692
693 foreach ($this->object->getOrderingElementList() as $element) {
694 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
695 $this->object->getId(),
696 0,
697 $element->getPosition()
698 );
699
700 if ($this->object->isImageOrderingType()) {
701 $imgSrc = $this->object->getImagePathWeb() . $element->getContent();
702 $tpl->setCurrentBlock('image');
703 $tpl->setVariable('IMG_SRC', $imgSrc);
704 } else {
705 $tpl->setCurrentBlock('text');
706 }
707 $tpl->setVariable('CONTENT', $element->getContent());
708 $tpl->parseCurrentBlock();
709
710 $tpl->setCurrentBlock('element');
711 $tpl->setVariable('FEEDBACK', $feedback);
712 $tpl->parseCurrentBlock();
713 }
714
715 return $this->object->prepareTextareaOutput($tpl->get(), true);
716 }
717
722 protected function persistAuthoringForm($form)
723 {
728 }
729
730 private function getOldLeveledOrdering()
731 {
732 global $DIC;
733 $ilDB = $DIC['ilDB'];
734
735 $res = $ilDB->queryF(
736 'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_key ASC',
737 array('integer'),
738 array($this->object->getId())
739 );
740 while ($row = $ilDB->fetchAssoc($res)) {
741 $this->old_ordering_depth[] = $row['depth'];
742 }
744 }
745
756 {
757 return array();
758 }
759
770 {
771 return array();
772 }
773
782 public function getAggregatedAnswersView($relevant_answers)
783 {
784 $aggView = $this->aggregateAnswers(
785 $relevant_answers,
786 $this->object->getOrderingElementList()
787 );
788
789 return $this->renderAggregateView($aggView)->get();
790 }
791
792 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
793 {
794 $passdata = array(); // Regroup answers into units of passes.
795 foreach ($relevant_answers_chosen as $answer_chosen) {
796 $passdata[$answer_chosen['active_fi'] . '-' . $answer_chosen['pass']][$answer_chosen['value2']] = $answer_chosen['value1'];
797 }
798
799 $variants = array(); // Determine unique variants.
800 foreach ($passdata as $key => $data) {
801 $hash = md5(implode('-', $data));
802 $value_set = false;
803 foreach ($variants as $vkey => $variant) {
804 if ($variant['hash'] == $hash) {
805 $variant['count']++;
806 $value_set = true;
807 }
808 }
809 if (!$value_set) {
810 $variants[$key]['hash'] = $hash;
811 $variants[$key]['count'] = 1;
812 }
813 }
814
815 $aggregate = array(); // Render aggregate from variant.
816 foreach ($variants as $key => $variant_entry) {
817 $variant = $passdata[$key];
818
819 foreach ($variant as $variant_key => $variant_line) {
820 $i = 0;
821 $aggregated_info_for_answer['count'] = $variant_entry['count'];
822 foreach ($answers_defined_on_question as $element) {
823 $i++;
824
825 if ($this->object->isImageOrderingType()) {
826 $element->setImageThumbnailPrefix($this->object->getThumbPrefix());
827 $element->setImagePathWeb($this->object->getImagePathWeb());
828 $element->setImagePathFs($this->object->getImagePath());
829
830 $src = $element->getPresentationImageUrl();
831 $alt = $element->getContent();
832 $content = "<img src='{$src}' alt='{$alt}' title='{$alt}'/>";
833 } else {
834 $content = $element->getContent();
835 }
836
837 $aggregated_info_for_answer[$i . ' - ' . $content]
838 = $passdata[$key][$i];
839 }
840 }
841 $aggregate[] = $aggregated_info_for_answer;
842 }
843 return $aggregate;
844 }
845
851 public function renderAggregateView($aggregate)
852 {
853 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
854
855 foreach ($aggregate as $line_data) {
856 $tpl->setCurrentBlock('aggregaterow');
857 $count = array_shift($line_data);
858 $html = '<ul>';
859 foreach ($line_data as $key => $line) {
860 $html .= '<li>' . ++$line . '&nbsp;-&nbsp;' . $key . '</li>';
861 }
862 $html .= '</ul>';
863 $tpl->setVariable('COUNT', $count);
864 $tpl->setVariable('OPTION', $html);
865
866 $tpl->parseCurrentBlock();
867 }
868 return $tpl;
869 }
870
872 {
873 if ($this->object->isImageOrderingType()) {
874 $element->setImageThumbnailPrefix($this->object->getThumbPrefix());
875 $element->setImagePathWeb($this->object->getImagePathWeb());
876 $element->setImagePathFs($this->object->getImagePath());
877
878 $src = $element->getPresentationImageUrl();
879 $alt = $element->getContent();
880 $content = "<img src='{$src}' alt='{$alt}' title='{$alt}'/>";
881 } else {
882 $content = $element->getContent();
883 }
884
885 return $content;
886 }
887
889 {
890 $html = '<ul>';
891
892 $lastIndent = 0;
893 $firstElem = true;
894
895 foreach ($list as $elem) {
896 if ($elem->getIndentation() > $lastIndent) {
897 $html .= '<ul><li>';
898 } elseif ($elem->getIndentation() < $lastIndent) {
899 $html .= '</li></ul><li>';
900 } elseif (!$firstElem) {
901 $html .= '</li><li>';
902 } else {
903 $html .= '<li>';
904 }
905
907
908 $firstElem = false;
909 $lastIndent = $elem->getIndentation();
910 }
911
912 $html .= '</li>';
913
914 for ($i = $lastIndent; $i > 0; $i--) {
915 $html .= '</ul></li>';
916 }
917
918 $html .= '</ul>';
919
920 return $html;
921 }
922
923 public function getAnswersFrequency($relevantAnswers, $questionIndex)
924 {
925 $answersByActiveAndPass = array();
926
927 foreach ($relevantAnswers as $row) {
928 $key = $row['active_fi'] . ':' . $row['pass'];
929
930 if (!isset($answersByActiveAndPass[$key])) {
931 $answersByActiveAndPass[$key] = array();
932 }
933
934 $answersByActiveAndPass[$key][$row['value1']] = $row['value2'];
935 }
936
937 $solutionLists = array();
938
939 foreach ($answersByActiveAndPass as $indexedSolutions) {
940 $solutionLists[] = $this->object->getSolutionOrderingElementList($indexedSolutions);
941 }
942
943 /* @var ilAssOrderingElementList[] $answers */
944 $answers = array();
945
946 foreach ($solutionLists as $orderingElementList) {
947 $hash = $orderingElementList->getHash();
948
949 if (!isset($answers[$hash])) {
950 $variantHtml = $this->getAnswerStatisticOrderingVariantHtml(
951 $orderingElementList
952 );
953
954 $answers[$hash] = array(
955 'answer' => $variantHtml, 'frequency' => 0
956 );
957 }
958
959 $answers[$hash]['frequency']++;
960 }
961
962 return array_values($answers);
963 }
964
969 {
970 $orderingInput = $form->getItemByPostVar(assOrderingQuestion::ORDERING_ELEMENT_FORM_FIELD_POSTVAR);
971 $orderingInput->prepareReprintable($this->object);
972 }
973
978 {
979 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
980 $points->allowDecimals(true);
981 $points->setValue($this->object->getPoints());
982 $points->setRequired(true);
983 $points->setSize(3);
984 $points->setMinValue(0);
985 $points->setMinvalueShouldBeGreater(true);
986 $form->addItem($points);
987
989 $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
990 $form->addItem($header);
991
992 $orderingElementInput = $this->object->buildNestedOrderingElementInputGui();
993
994 $this->object->initOrderingElementAuthoringProperties($orderingElementInput);
995
996 $orderingElementInput->setElementList($this->object->getOrderingElementList());
997
998 $form->addItem($orderingElementInput);
999 }
1000
1005 {
1006 $this->object->setPoints((float) $form->getInput('points'));
1007
1008 $submittedElementList = $this->object->fetchSolutionListFromSubmittedForm($form);
1009
1010 $curElementList = $this->object->getOrderingElementList();
1011
1012 $newElementList = new ilAssOrderingElementList();
1013 $newElementList->setQuestionId($this->object->getId());
1014
1015 foreach ($submittedElementList as $submittedElement) {
1016 if (!$curElementList->elementExistByRandomIdentifier($submittedElement->getRandomIdentifier())) {
1017 continue;
1018 }
1019
1020 $curElement = $curElementList->getElementByRandomIdentifier($submittedElement->getRandomIdentifier());
1021
1022 $curElement->setPosition($submittedElement->getPosition());
1023
1024 if ($this->object->isOrderingTypeNested()) {
1025 $curElement->setIndentation($submittedElement->getIndentation());
1026 }
1027
1028 $newElementList->addElement($curElement);
1029 }
1030
1031 $this->object->setOrderingElementList($newElementList);
1032 }
1033}
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Ordering question GUI representation.
prepareReprintableCorrectionsForm(ilPropertyFormGUI $form)
setQuestionTabs()
Sets the ILIAS tabs for this question type.
getAnswersFrequency($relevantAnswers, $questionIndex)
getPreview($show_question_only=false, $showInlineFeedback=false)
__construct($id=-1)
assOrderingQuestionGUI constructor
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $forceCorrectSolution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
Adds the answer specific form parts to a question property form gui.
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
getAnswerStatisticOrderingElementHtml(ilAssOrderingElement $element)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
setClearAnswersOnWritingPostDataEnabled($clearAnswersOnWritingPostDataEnabled)
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
writePostData($forceSaving=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getAnswerStatisticOrderingVariantHtml(ilAssOrderingElementList $list)
getTestOutput($activeId, $pass, $isPostponed=false, $userSolutionPost=false, $inlineFeedback=false)
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
Class for ordering questions.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
getILIASPage($html="")
Returns the ILIAS Page around a question.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
addBackTab(ilTabsGUI $ilTabs)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
static buildInstance($questionId, $orderingElements=array())
setImageThumbnailPrefix($imageThumbnailPrefix)
This class represents a section header in a property form.
This class represents a number property in a property form.
This class represents a property form user interface.
getInput($a_post_var, $ensureValidation=true)
Returns the value of a HTTP-POST variable, identified by the passed id.
special template class to simplify handling of ITX/PEAR
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$template
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
$html
Definition: example_001.php:87
if(!array_key_exists('StateId', $_REQUEST)) $id
const OQ_NESTED_PICTURES
const OQ_TERMS
const OQ_NESTED_TERMS
const OQ_PICTURES
Ordering question constants.
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$row
$url
if(isset($_POST['submit'])) $form
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$data
Definition: bench.php:6