ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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 {
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();
82 $this->persistAuthoringForm($form);
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();
99 $this->persistAuthoringForm($form);
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
182 $this->writeAnswerSpecificPostData($form);
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 {
281 $header = new ilFormSectionHeaderGUI();
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->isImageOrderingType()) {
304 $geometry = new ilNumberInputGUI($this->lng->txt("thumb_geometry"), "thumb_geometry");
305 $geometry->setValue($this->object->getThumbGeometry());
306 $geometry->setRequired(true);
307 $geometry->setMaxLength(6);
308 $geometry->setMinValue(20);
309 $geometry->setSize(6);
310 $geometry->setInfo($this->lng->txt("thumb_geometry_info"));
311 $form->addItem($geometry);
312 }
313
314 // points
315 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
316 $points->allowDecimals(true);
317 $points->setValue($this->object->getPoints());
318 $points->setRequired(true);
319 $points->setSize(3);
320 $points->setMinValue(0);
321 $points->setMinvalueShouldBeGreater(true);
322 $form->addItem($points);
323
324 return $form;
325 }
326
330 protected function writePostData($forceSaving = false)
331 {
332 $savingAllowed = true; // assume saving allowed first
333
334 if (!$forceSaving) {
335 // this case seems to be a regular save call, so we consider
336 // the validation result for the decision of saving as well
337
338 // inits {this->editForm} and performs validation
339 $form = $this->buildEditForm();
340 $form->setValuesByPost(); // manipulation and distribution of values
341
342 if (!$form->checkInput()) { // manipulations regular style input propeties
343 $form->prepareValuesReprintable($this->object);
344 $this->renderEditForm($form);
345
346 // consequence of vaidation
347 $savingAllowed = false;
348 }
349 } elseif (!$this->isSaveCommand()) {
350 // this case handles form workflow actions like the mode/view switching requests,
351 // so saving must not be skipped, even for inputs invalid by business rules
352
353 $form = $this->buildEditForm();
354 $form->setValuesByPost(); // manipulation and distribution of values
355 $form->checkInput(); // manipulations regular style input propeties
356 }
357
358 if ($savingAllowed) {
359 $this->persistAuthoringForm($form);
360
361 return 0; // return 0 = all fine, was saved either forced or validated
362 }
363
364 return 1; // return 1 = something went wrong, no saving happened
365 }
366
370 public function editQuestion($checkonly = false)
371 {
372 $this->renderEditForm($this->buildEditForm());
373 }
374
378 protected function buildEditForm()
379 {
380 require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingQuestionAuthoringFormGUI.php';
382 $this->editForm = $form;
383
384 $form->setFormAction($this->ctrl->getFormAction($this));
385 $form->setTitle($this->outQuestionType());
386 $form->setMultipart(($this->object->getOrderingType() == OQ_PICTURES) ? true : false);
387 $form->setTableWidth("100%");
388 $form->setId("ordering");
389 // title, author, description, question, working time (assessment mode)
390 $this->addBasicQuestionFormProperties($form);
392 $this->populateAnswerSpecificFormPart($form);
393
394 $this->populateTaxonomyFormSection($form);
395
396 $form->addSpecificOrderingQuestionCommandButtons($this->object);
397 $form->addGenericAssessmentQuestionCommandButtons($this->object);
398
399 return $form;
400 }
401
408 {
409 return true;
410 }
411
427 public function getSolutionOutput(
428 $active_id,
429 $pass = null,
430 $graphicalOutput = false,
431 $result_output = false,
432 $show_question_only = true,
433 $show_feedback = false,
434 $forceCorrectSolution = false,
435 $show_manual_scoring = false,
436 $show_question_text = true
437 ) {
438 $solutionOrderingList = $this->object->getOrderingElementListForSolutionOutput(
439 $forceCorrectSolution,
440 $active_id,
441 $pass,
443 );
444
445 $answers_gui = $this->object->buildNestedOrderingElementInputGui();
446
447 if ($forceCorrectSolution) {
449 } else {
451 }
452
453 $answers_gui->setInteractionEnabled(false);
454
455 $answers_gui->setElementList($solutionOrderingList);
456
457 $answers_gui->setCorrectnessTrueElementList(
458 $solutionOrderingList->getParityTrueElementList($this->object->getOrderingElementList())
459 );
460
461 $solution_html = $answers_gui->getHTML();
462
463 $template = new ilTemplate("tpl.il_as_qpl_nested_ordering_output_solution.html", true, true, "Modules/TestQuestionPool");
464 $template->setVariable('SOLUTION_OUTPUT', $solution_html);
465 if ($show_question_text == true) {
466 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
467 }
468 $questionoutput = $template->get();
469
470 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
471 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
472
473 if ($show_feedback) {
474 $feedback = '';
475
476 if (!$this->isTestPresentationContext()) {
477 $fb = $this->getGenericFeedbackOutput($active_id, $pass);
478 $feedback .= strlen($fb) ? $fb : '';
479 }
480
481 $fb = $this->getSpecificFeedbackOutput(array());
482 $feedback .= strlen($fb) ? $fb : '';
483
484 if (strlen($feedback)) {
485 $cssClass = (
486 $this->hasCorrectSolution($active_id, $pass) ?
488 );
489
490 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
491 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
492 }
493 }
494
495 if ($show_question_only) {
496 return $solutiontemplate->get();
497 }
498
499 return $this->getILIASPage($solutiontemplate->get());
500
501 // is this template still in use? it is not used at this point any longer!
502 // $template = new ilTemplate("tpl.il_as_qpl_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
503 }
504
505 public function getPreview($show_question_only = false, $showInlineFeedback = false)
506 {
507 if ($this->getPreviewSession() && $this->getPreviewSession()->hasParticipantSolution()) {
508 $solutionOrderingElementList = unserialize(
509 $this->getPreviewSession()->getParticipantsSolution()
510 );
511 } else {
512 $solutionOrderingElementList = $this->object->getShuffledOrderingElementList();
513 }
514
515 $answers = $this->object->buildNestedOrderingElementInputGui();
516 $answers->setNestingEnabled($this->object->isOrderingTypeNested());
518 $answers->setInteractionEnabled($this->isInteractivePresentation());
519 $answers->setElementList($solutionOrderingElementList);
520
521 $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", true, true, "Modules/TestQuestionPool");
522
523 $template->setCurrentBlock('nested_ordering_output');
524 $template->setVariable('NESTED_ORDERING', $answers->getHTML());
525 $template->parseCurrentBlock();
526
527 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
528
529 if ($show_question_only) {
530 return $template->get();
531 }
532
533 return $this->getILIASPage($template->get());
534
535 //$this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/ordering.js");
536 }
537
539 {
540 global $DIC; /* @var ILIAS\DI\Container $DIC */
541
542 $files = array();
543
544 if ($DIC['ilBrowser']->isMobile() || $DIC['ilBrowser']->isIpad()) {
545 $files[] = './libs/bower/bower_components/jqueryui-touch-punch/jquery.ui.touch-punch.min.js';
546 }
547
548 return $files;
549 }
550
551 // hey: prevPassSolutions - pass will be always available from now on
552 public function getTestOutput($activeId, $pass, $isPostponed = false, $userSolutionPost = false, $inlineFeedback = false)
553 // hey.
554 {
555 // hey: prevPassSolutions - fixed variable type, makes phpstorm stop crying
556 $userSolutionPost = is_array($userSolutionPost) ? $userSolutionPost : array();
557 // hey.
558
559 $orderingGUI = $this->object->buildNestedOrderingElementInputGui();
560 $orderingGUI->setNestingEnabled($this->object->isOrderingTypeNested());
561
562 $solutionOrderingElementList = $this->object->getSolutionOrderingElementListForTestOutput(
563 $orderingGUI,
564 $userSolutionPost,
565 $activeId,
566 $pass
567 );
568
569 $template = new ilTemplate('tpl.il_as_qpl_ordering_output.html', true, true, 'Modules/TestQuestionPool');
570
572 $orderingGUI->setElementList($solutionOrderingElementList);
573
574 $template->setCurrentBlock('nested_ordering_output');
575 $template->setVariable('NESTED_ORDERING', $orderingGUI->getHTML());
576 $template->parseCurrentBlock();
577
578 $template->setVariable('QUESTIONTEXT', $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
579
580 $pageoutput = $this->outQuestionPage('', $isPostponed, $activeId, $template->get());
581
582 return $pageoutput;
583 }
584
585 protected function isInteractivePresentation()
586 {
587 if ($this->isRenderPurposePlayback()) {
588 return true;
589 }
590
591 if ($this->isRenderPurposeDemoplay()) {
592 return true;
593 }
594
595 return false;
596 }
597
605 public function setQuestionTabs()
606 {
607 global $DIC;
608 $rbacsystem = $DIC['rbacsystem'];
609 $ilTabs = $DIC['ilTabs'];
610
611 $ilTabs->clearTargets();
612
613 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
614 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
615 $q_type = $this->object->getQuestionType();
616
617 if (strlen($q_type)) {
618 $classname = $q_type . "GUI";
619 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
620 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
621 }
622
623 if ($_GET["q_id"]) {
624 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
625 // edit page
626 $ilTabs->addTarget(
627 "edit_page",
628 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
629 array("edit", "insert", "exec_pg"),
630 "",
631 "",
632 false
633 );
634 }
635
636 $this->addTab_QuestionPreview($ilTabs);
637 }
638
639 $force_active = false;
640 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
641 $url = "";
642 if ($classname) {
643 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
644 }
645 $commands = $_POST["cmd"];
646 if (is_array($commands)) {
647 foreach ($commands as $key => $value) {
648 if (preg_match("/^delete_.*/", $key, $matches)) {
649 $force_active = true;
650 }
651 }
652 }
653 // edit question properties
654 $ilTabs->addTarget(
655 "edit_question",
656 $url,
657 array("orderNestedTerms","orderNestedPictures","editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "changeToPictures", "uploadElementImage", "changeToText", "upanswers", "downanswers", "originalSyncForm"),
658 $classname,
659 "",
660 $force_active
661 );
662 }
663
664 // add tab for question feedback within common class assQuestionGUI
665 $this->addTab_QuestionFeedback($ilTabs);
666
667 // add tab for question hint within common class assQuestionGUI
668 $this->addTab_QuestionHints($ilTabs);
669
670 // add tab for question's suggested solution within common class assQuestionGUI
671 $this->addTab_SuggestedSolution($ilTabs, $classname);
672
673 // Assessment of questions sub menu entry
674 if ($_GET["q_id"]) {
675 $ilTabs->addTarget(
676 "statistics",
677 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
678 array("assessment"),
679 $classname,
680 ""
681 );
682 }
683
684 $this->addBackTab($ilTabs);
685 }
686
687 public function getSpecificFeedbackOutput($userSolution)
688 {
689 if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
690 return '';
691 }
692
693 $tpl = new ilTemplate('tpl.il_as_qpl_ordering_elem_fb.html', true, true, 'Modules/TestQuestionPool');
694
695 foreach ($this->object->getOrderingElementList() as $element) {
696 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
697 $this->object->getId(),
698 0,
699 $element->getPosition()
700 );
701
702 if ($this->object->isImageOrderingType()) {
703 $imgSrc = $this->object->getImagePathWeb() . $element->getContent();
704 $tpl->setCurrentBlock('image');
705 $tpl->setVariable('IMG_SRC', $imgSrc);
706 } else {
707 $tpl->setCurrentBlock('text');
708 }
709 $tpl->setVariable('CONTENT', $element->getContent());
710 $tpl->parseCurrentBlock();
711
712 $tpl->setCurrentBlock('element');
713 $tpl->setVariable('FEEDBACK', $feedback);
714 $tpl->parseCurrentBlock();
715 }
716
717 return $this->object->prepareTextareaOutput($tpl->get(), true);
718 }
719
724 protected function persistAuthoringForm($form)
725 {
727 $this->writeQuestionSpecificPostData($form);
728 $this->writeAnswerSpecificPostData($form);
730 }
731
732 private function getOldLeveledOrdering()
733 {
734 global $DIC;
735 $ilDB = $DIC['ilDB'];
736
737 $res = $ilDB->queryF(
738 'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_key ASC',
739 array('integer'),
740 array($this->object->getId())
741 );
742 while ($row = $ilDB->fetchAssoc($res)) {
743 $this->old_ordering_depth[] = $row['depth'];
744 }
746 }
747
758 {
759 return array();
760 }
761
772 {
773 return array();
774 }
775
784 public function getAggregatedAnswersView($relevant_answers)
785 {
786 $aggView = $this->aggregateAnswers(
787 $relevant_answers,
788 $this->object->getOrderingElementList()
789 );
790
791 return $this->renderAggregateView($aggView)->get();
792 }
793
794 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
795 {
796 $passdata = array(); // Regroup answers into units of passes.
797 foreach ($relevant_answers_chosen as $answer_chosen) {
798 $passdata[$answer_chosen['active_fi'] . '-' . $answer_chosen['pass']][$answer_chosen['value2']] = $answer_chosen['value1'];
799 }
800
801 $variants = array(); // Determine unique variants.
802 foreach ($passdata as $key => $data) {
803 $hash = md5(implode('-', $data));
804 $value_set = false;
805 foreach ($variants as $vkey => $variant) {
806 if ($variant['hash'] == $hash) {
807 $variant['count']++;
808 $value_set = true;
809 }
810 }
811 if (!$value_set) {
812 $variants[$key]['hash'] = $hash;
813 $variants[$key]['count'] = 1;
814 }
815 }
816
817 $aggregate = array(); // Render aggregate from variant.
818 foreach ($variants as $key => $variant_entry) {
819 $variant = $passdata[$key];
820
821 foreach ($variant as $variant_key => $variant_line) {
822 $i = 0;
823 $aggregated_info_for_answer['count'] = $variant_entry['count'];
824 foreach ($answers_defined_on_question as $element) {
825 $i++;
826
827 if ($this->object->isImageOrderingType()) {
828 $element->setImageThumbnailPrefix($this->object->getThumbPrefix());
829 $element->setImagePathWeb($this->object->getImagePathWeb());
830 $element->setImagePathFs($this->object->getImagePath());
831
832 $src = $element->getPresentationImageUrl();
833 $alt = $element->getContent();
834 $content = "<img src='{$src}' alt='{$alt}' title='{$alt}'/>";
835 } else {
836 $content = $element->getContent();
837 }
838
839 $aggregated_info_for_answer[$i . ' - ' . $content]
840 = $passdata[$key][$i];
841 }
842 }
843 $aggregate[] = $aggregated_info_for_answer;
844 }
845 return $aggregate;
846 }
847
853 public function renderAggregateView($aggregate)
854 {
855 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
856
857 foreach ($aggregate as $line_data) {
858 $tpl->setCurrentBlock('aggregaterow');
859 $count = array_shift($line_data);
860 $html = '<ul>';
861 foreach ($line_data as $key => $line) {
862 $html .= '<li>' . ++$line . '&nbsp;-&nbsp;' . $key . '</li>';
863 }
864 $html .= '</ul>';
865 $tpl->setVariable('COUNT', $count);
866 $tpl->setVariable('OPTION', $html);
867
868 $tpl->parseCurrentBlock();
869 }
870 return $tpl;
871 }
872
874 {
875 if ($this->object->isImageOrderingType()) {
876 $element->setImageThumbnailPrefix($this->object->getThumbPrefix());
877 $element->setImagePathWeb($this->object->getImagePathWeb());
878 $element->setImagePathFs($this->object->getImagePath());
879
880 $src = $element->getPresentationImageUrl();
881 $alt = $element->getContent();
882 $content = "<img src='{$src}' alt='{$alt}' title='{$alt}'/>";
883 } else {
884 $content = $element->getContent();
885 }
886
887 return $content;
888 }
889
891 {
892 $html = '<ul>';
893
894 $lastIndent = 0;
895 $firstElem = true;
896
897 foreach ($list as $elem) {
898 if ($elem->getIndentation() > $lastIndent) {
899 $html .= '<ul><li>';
900 } elseif ($elem->getIndentation() < $lastIndent) {
901 $html .= '</li></ul><li>';
902 } elseif (!$firstElem) {
903 $html .= '</li><li>';
904 } else {
905 $html .= '<li>';
906 }
907
908 $html .= $this->getAnswerStatisticOrderingElementHtml($elem);
909
910 $firstElem = false;
911 $lastIndent = $elem->getIndentation();
912 }
913
914 $html .= '</li>';
915
916 for ($i = $lastIndent; $i > 0; $i--) {
917 $html .= '</ul></li>';
918 }
919
920 $html .= '</ul>';
921
922 return $html;
923 }
924
925 public function getAnswersFrequency($relevantAnswers, $questionIndex)
926 {
927 $answersByActiveAndPass = array();
928
929 foreach ($relevantAnswers as $row) {
930 $key = $row['active_fi'] . ':' . $row['pass'];
931
932 if (!isset($answersByActiveAndPass[$key])) {
933 $answersByActiveAndPass[$key] = array();
934 }
935
936 $answersByActiveAndPass[$key][$row['value1']] = $row['value2'];
937 }
938
939 $solutionLists = array();
940
941 foreach ($answersByActiveAndPass as $indexedSolutions) {
942 $solutionLists[] = $this->object->getSolutionOrderingElementList($indexedSolutions);
943 }
944
945 /* @var ilAssOrderingElementList[] $answers */
946 $answers = array();
947
948 foreach ($solutionLists as $orderingElementList) {
949 $hash = $orderingElementList->getHash();
950
951 if (!isset($answers[$hash])) {
952 $variantHtml = $this->getAnswerStatisticOrderingVariantHtml(
953 $orderingElementList
954 );
955
956 $answers[$hash] = array(
957 'answer' => $variantHtml, 'frequency' => 0
958 );
959 }
960
961 $answers[$hash]['frequency']++;
962 }
963
964 return array_values($answers);
965 }
966
971 {
973 $orderingInput->prepareReprintable($this->object);
974 }
975
980 {
981 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
982 $points->allowDecimals(true);
983 $points->setValue($this->object->getPoints());
984 $points->setRequired(true);
985 $points->setSize(3);
986 $points->setMinValue(0);
987 $points->setMinvalueShouldBeGreater(true);
988 $form->addItem($points);
989
990 $header = new ilFormSectionHeaderGUI();
991 $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
992 $form->addItem($header);
993
994 $orderingElementInput = $this->object->buildNestedOrderingElementInputGui();
995
996 $this->object->initOrderingElementAuthoringProperties($orderingElementInput);
997
998 $orderingElementInput->setElementList($this->object->getOrderingElementList());
999
1000 $form->addItem($orderingElementInput);
1001 }
1002
1007 {
1008 $this->object->setPoints((float) $form->getInput('points'));
1009
1010 $submittedElementList = $this->object->fetchSolutionListFromSubmittedForm($form);
1011
1012 $curElementList = $this->object->getOrderingElementList();
1013
1014 $newElementList = new ilAssOrderingElementList();
1015 $newElementList->setQuestionId($this->object->getId());
1016
1017 foreach ($submittedElementList as $submittedElement) {
1018 if (!$curElementList->elementExistByRandomIdentifier($submittedElement->getRandomIdentifier())) {
1019 continue;
1020 }
1021
1022 $curElement = $curElementList->getElementByRandomIdentifier($submittedElement->getRandomIdentifier());
1023
1024 $curElement->setPosition($submittedElement->getPosition());
1025
1026 if ($this->object->isOrderingTypeNested()) {
1027 $curElement->setIndentation($submittedElement->getIndentation());
1028 }
1029
1030 $newElementList->addElement($curElement);
1031 }
1032
1033 $this->object->setOrderingElementList($newElementList);
1034 }
1035}
$_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.
addItem($a_item)
Add Item (Property, SectionHeader).
getInput($a_post_var, $ensureValidation=true)
Returns the value of a HTTP-POST variable, identified by the passed id.
getItemByPostVar($a_post_var)
Get Item by POST variable.
special template class to simplify handling of ITX/PEAR
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
const OQ_NESTED_PICTURES
const OQ_TERMS
const OQ_NESTED_TERMS
const OQ_PICTURES
Ordering question constants.
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$url
foreach($_POST as $key=> $value) $res
global $ilDB
$data
Definition: storeScorm.php:23
$DIC
Definition: xapitoken.php:46