ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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
23{
24 private $uploadAlert = null;
25
26 public $old_ordering_depth = array();
27 public $leveled_ordering = array();
28
33
43 public function __construct($id = -1)
44 {
45 parent::__construct();
46 include_once "./Modules/TestQuestionPool/classes/class.assOrderingQuestion.php";
47 $this->object = new assOrderingQuestion();
48 if ($id >= 0)
49 {
50 $this->object->loadFromDb($id);
51 }
52 $this->object->setOutputType(OUTPUT_JAVASCRIPT);
53
54 $this->clearAnswersOnWritingPostDataEnabled = false;
55 }
56
61 {
62 $this->clearAnswersOnWritingPostDataEnabled = $clearAnswersOnWritingPostDataEnabled;
63 }
64
69 {
71 }
72
73 public function changeToPictures()
74 {
75 if($this->object->getOrderingType() != OQ_NESTED_PICTURES && $this->object->getOrderingType() != OQ_PICTURES)
76 {
78 }
79
80 $this->object->setOrderingType(OQ_PICTURES);
81 $this->writePostData(true);
82 $this->object->saveToDb();
83
84 $this->editQuestion();
85 }
86
87 public function changeToText()
88 {
89 if($this->object->getOrderingType() != OQ_NESTED_TERMS && $this->object->getOrderingType() != OQ_TERMS)
90 {
92 }
93
94 $this->object->setOrderingType(OQ_TERMS);
95 $this->writePostData(true);
96 $this->object->saveToDb();
97
98 $this->editQuestion();
99 }
100
101 public function orderNestedTerms()
102 {
103 if($this->object->getOrderingType() != OQ_NESTED_TERMS && $this->object->getOrderingType() != OQ_TERMS)
104 {
106 }
107
108 $this->object->setOrderingType(OQ_NESTED_TERMS);
109 $this->writePostData(true);
110 $this->object->saveToDb();
111
112 $this->editQuestion();
113 }
114
115 public function orderNestedPictures()
116 {
117 $this->object->setOrderingType(OQ_NESTED_PICTURES);
118 $this->writePostData(true);
119 $this->object->saveToDb();
120
121 $this->editQuestion();
122 }
123
124 public function addanswers()
125 {
126 $this->writePostData(true);
127 $position = key($_POST["cmd"]["addanswers"]);
128 $this->object->addAnswer("", $position+1);
129 $this->editQuestion();
130 }
131
132 public function removeimageanswers()
133 {
134 $this->writePostData(true);
135 $position = key($_POST['cmd']['removeimageanswers']);
136 $filename = $_POST['answers']['imagename'][$position];
137 $this->object->removeAnswerImage($position);
138 $this->editQuestion();
139 }
140
141 public function removeanswers()
142 {
143 $this->writePostData(true);
144 $position = key($_POST["cmd"]["removeanswers"]);
145 $this->object->deleteAnswer($position);
146 $this->editQuestion();
147 }
148
149 public function upanswers()
150 {
151 $this->writePostData(true);
152 $position = key($_POST["cmd"]["upanswers"]);
153 $this->object->moveAnswerUp($position);
154 $this->editQuestion();
155 }
156
157 public function downanswers()
158 {
159 $this->writePostData(true);
160 $position = key($_POST["cmd"]["downanswers"]);
161 $this->object->moveAnswerDown($position);
162 $this->editQuestion();
163 }
164
169 {
170 include_once "./Modules/TestQuestionPool/classes/class.ilImageWizardInputGUI.php";
171 $answers = new ilImageWizardInputGUI($this->lng->txt("answers"), "answers");
172 $answers->setRequired(TRUE);
173 $answers->setQuestionObject($this->object);
174 $answers->setInfo($this->lng->txt('ordering_answer_sequence_info'));
175 $answers->setAllowMove(TRUE);
176 $answervalues = array();
177 foreach ($this->object->getAnswers() as $index => $answervalue)
178 {
179 $answervalues[$index] = $answervalue->getAnswertext();
180 }
181 $answers->setValues($answervalues);
182 return $answers;
183 }
184
185 public function uploadanswers()
186 {
187 $this->lng->loadLanguageModule('form');
188
190
191 if( !$inp->checkInput() )
192 {
193 $this->uploadAlert = $inp->getAlert();
194 ilUtil::sendFailure($inp->getAlert());
195 }
196
197 $this->writePostData(true);
198 $this->editQuestion();
199 }
200
202 {
203 $this->object->setThumbGeometry( $_POST["thumb_geometry"] );
204 $this->object->setElementHeight( $_POST["element_height"] );
205 //$this->object->setOrderingType( $_POST["ordering_type"] );
206 $this->object->setPoints($_POST["points"]);
207 }
208
210 {
211 $ordering_type = $this->object->getOrderingType();
212 // Delete all existing answers and create new answers from the form data
213 $this->object->flushAnswers();
214 $saved = false;
215
216 // add answers
217 if ($ordering_type == OQ_TERMS
218 || $ordering_type == OQ_NESTED_TERMS
219 || $ordering_type == OQ_NESTED_PICTURES
220 )
221 {
222 $answers = $_POST["answers"];
223 if (is_array( $answers ))
224 {
226 $answers_ordering = $_POST['answers_ordering__default']; // __default is added by js
227 $new_hierarchy = json_decode( $answers_ordering );
228
229 $this->getOldLeveledOrdering();
230
231 if (!is_array( $new_hierarchy ))
232 {
233 $this->leveled_ordering = $this->old_ordering_depth;
234 }
235 else
236 {
237 $this->setLeveledOrdering( $new_hierarchy );
238 }
239
240 $counter = 0;
241
242 if(is_array($answers['imagename']))
243 {
244 foreach($answers['imagename'] as $index => $answer)
245 {
247 {
248 $answer = "";
249 }
250 $this->object->addAnswer($answer, -1, $this->leveled_ordering[$counter]);
251 $counter++;
252 }
253 }
254 else
255 {
256 foreach($answers as $index => $answer)
257 {
259 {
260 $answer = "";
261 }
262 $this->object->addAnswer($answer, -1, $this->leveled_ordering[$counter]);
263 $counter++;
264 }
265 }
266 }
267 }
268 else
269 {
270 if (is_array( $_POST['answers']['count'] ))
271 {
272 foreach (array_keys( $_POST['answers']['count'] ) as $index)
273 {
275 {
276 $this->object->addAnswer( "" );
277 continue;
278 }
279
280 $picturefile = $_POST['answers']['imagename'][$index];
281 $file_org_name = $_FILES['answers']['name']['image'][$index];
282 $file_temp_name = $_FILES['answers']['tmp_name']['image'][$index];
283
284 // new file
285 if (strlen( $file_temp_name ))
286 {
287 // check suffix
288 $suffix = strtolower( array_pop( explode( ".", $file_org_name ) ) );
289 if (in_array( $suffix, array( "jpg", "jpeg", "png", "gif" ) ))
290 {
291 // upload image
292 $filename = $this->object->createNewImageFileName( $file_org_name );
293 $filename = $this->object->getEncryptedFilename( $filename );
294 if ($this->object->setImageFile( $file_temp_name, $filename, $picturefile ))
295 {
296 $picturefile = $filename;
297 }
298 }
299 }
300
301 $this->object->addAnswer( $picturefile );
302 }
303 }
304 else if(is_array($_POST['answers']))
305 {
306 foreach($_POST['answers'] as $random_id => $text_value)
307 {
308 $this->object->addAnswer( $text_value );
309 }
310 }
311 }
312 }
313
315 {
316 $orderingtype = $this->object->getOrderingType();
317
318 if (count($this->object->getAnswers()) == 0)
319 {
320 $this->object->addAnswer();
321 }
322
324 $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
325 $form->addItem($header);
326
327 if ($orderingtype == OQ_PICTURES)
328 {
329 $answerImageUpload = $this->getAnswerImageFileUploadWizardFormProperty();
330 if ($this->uploadAlert !== null)
331 {
332 $answerImageUpload->setAlert( $this->uploadAlert );
333 }
334 $form->addItem( $answerImageUpload );
335 }
336 else if ($orderingtype == OQ_NESTED_TERMS || $orderingtype == OQ_NESTED_PICTURES)
337 {
338 require_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
339 $answers = new ilNestedOrderingGUI($this->lng->txt( "answers" ), "answers");
340 $answers->setOrderingType( $orderingtype );
341 $answers->setObjAnswersArray( $this->object->getAnswers() );
342
343 if ($orderingtype == OQ_NESTED_PICTURES)
344 {
345 $answers->setImagePath( $this->object->getImagePath() );
346 $answers->setImagePathWeb( $this->object->getImagePathWeb() );
347 $answers->setThumbPrefix( $this->object->getThumbPrefix() );
348 }
349 $answers->setInfo( $this->lng->txt( 'ordering_answer_sequence_info' ) );
350 $form->addItem( $answers );
351 }
352 else
353 {
354 $answers = new ilTextWizardInputGUI($this->lng->txt( "answers" ), "answers");
355 $answervalues = array();
356 foreach ($this->object->getAnswers() as $index => $answervalue)
357 {
358 $answervalues[$index] = $answervalue->getAnswertext();
359 }
360 ksort( $answervalues );
361 $answers->setValues( $answervalues );
362 $answers->setAllowMove( TRUE );
363 $answers->setRequired( TRUE );
364
365 $answers->setInfo( $this->lng->txt( 'ordering_answer_sequence_info' ) );
366 $form->addItem( $answers );
367 }
368
369 return $form;
370 }
371
373 {
374 $orderingtype = $this->object->getOrderingType();
375
376 // Edit mode
377
378 //$hidden = new ilHiddenInputGUI("ordering_type");
379 //$hidden->setValue( $orderingtype );
380 //$form->addItem( $hidden );
381
382 if (!$this->object->getSelfAssessmentEditingMode())
383 {
384 $element_height = new ilNumberInputGUI($this->lng->txt( "element_height" ), "element_height");
385 $element_height->setValue( $this->object->getElementHeight() );
386 $element_height->setRequired( false );
387 $element_height->setMaxLength( 6 );
388 $element_height->setMinValue( 20 );
389 $element_height->setSize( 6 );
390 $element_height->setInfo( $this->lng->txt( "element_height_info" ) );
391 $form->addItem( $element_height );
392 }
393
394 if ($orderingtype == OQ_PICTURES)
395 {
396 $geometry = new ilNumberInputGUI($this->lng->txt( "thumb_geometry" ), "thumb_geometry");
397 $geometry->setValue( $this->object->getThumbGeometry() );
398 $geometry->setRequired( true );
399 $geometry->setMaxLength( 6 );
400 $geometry->setMinValue( 20 );
401 $geometry->setSize( 6 );
402 $geometry->setInfo( $this->lng->txt( "thumb_geometry_info" ) );
403 $form->addItem( $geometry );
404 }
405
406 // points
407 $points = new ilNumberInputGUI($this->lng->txt( "points" ), "points");
408 $points->allowDecimals( true );
409 $points->setValue( $this->object->getPoints() );
410 $points->setRequired( TRUE );
411 $points->setSize( 3 );
412 $points->setMinValue( 0 );
413 $points->setMinvalueShouldBeGreater( true );
414 $form->addItem( $points );
415
416 return $form;
417 }
418
419 private function isUploadAnswersCommand()
420 {
421 return $this->ctrl->getCmd() == 'uploadanswers';
422 }
423
432 public function writePostData($always = false)
433 {
434 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
435 if (!$hasErrors)
436 {
437 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
442 return 0;
443 }
444
445 return 1;
446 }
447
451 public function editQuestion($checkonly = FALSE)
452 {
453 $save = $this->isSaveCommand();
454 $this->getQuestionTemplate();
455
456 $orderingtype = $this->object->getOrderingType();
457
458 require_once "./Services/Form/classes/class.ilPropertyFormGUI.php";
459 $form = new ilPropertyFormGUI();
460 $form->setFormAction($this->ctrl->getFormAction($this));
461 $form->setTitle($this->outQuestionType());
462 $form->setMultipart(($orderingtype == OQ_PICTURES) ? TRUE : FALSE);
463 $form->setTableWidth("100%");
464 $form->setId("ordering");
465 // title, author, description, question, working time (assessment mode)
466 $this->addBasicQuestionFormProperties( $form );
468 $this->populateAnswerSpecificFormPart( $form );
469
470 if (true || !$this->object->getSelfAssessmentEditingMode())
471 {
472 $this->populateCommandButtons($form);
473 }
474
475 $this->populateTaxonomyFormSection($form);
476 $this->addQuestionFormCommandButtons($form);
477 $errors = false;
478 if ($save)
479 {
480 $form->setValuesByPost();
481 $errors = !$form->checkInput();
482 $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we need this if we don't want to have duplication of backslashes
483 if ($errors) $checkonly = false;
484 }
485
486 if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
487 return $errors;
488 }
489
491 {
492 switch( $this->object->getOrderingType() )
493 {
494 case OQ_TERMS:
495
496 $form->addCommandButton("changeToPictures", $this->lng->txt("oq_btn_use_order_pictures"));
497 $form->addCommandButton("orderNestedTerms", $this->lng->txt("oq_btn_nest_terms"));
498 break;
499
500 case OQ_PICTURES:
501
502 $form->addCommandButton("changeToText", $this->lng->txt("oq_btn_use_order_terms"));
503 $form->addCommandButton("orderNestedPictures", $this->lng->txt("oq_btn_nest_pictures"));
504 break;
505
506 case OQ_NESTED_TERMS:
507
508 $form->addCommandButton("changeToPictures", $this->lng->txt("oq_btn_use_order_pictures"));
509 $form->addCommandButton("changeToText", $this->lng->txt("oq_btn_define_terms"));
510 break;
511
513
514 $form->addCommandButton("changeToText", $this->lng->txt("oq_btn_use_order_terms"));
515 $form->addCommandButton("changeToPictures", $this->lng->txt("oq_btn_define_pictures"));
516 break;
517 }
518 }
519
536 $active_id,
537 $pass = NULL,
538 $graphicalOutput = FALSE,
539 $result_output = FALSE,
540 $show_question_only = TRUE,
541 $show_feedback = FALSE,
542 $show_correct_solution = FALSE,
543 $show_manual_scoring = FALSE,
544 $show_question_text = TRUE
545 )
546 {
547 if($this->object->getOrderingType() == OQ_NESTED_TERMS
548 || $this->object->getOrderingType() == OQ_NESTED_PICTURES)
549 {
550
551 // generate the question output
552 include_once "./Services/UICore/classes/class.ilTemplate.php";
553 $template = new ilTemplate("tpl.il_as_qpl_nested_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
554
555 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
556
557 // get the solution of the user for the active pass or from the last pass if allowed
558 $solutions = array();
559
560 if (($active_id > 0) && (!$show_correct_solution))
561 {
562 $solutions = $this->object->getSolutionValues($active_id, $pass);
563 $user_order = array();
564 foreach ($solutions as $solution)
565 {
566 if(strchr( $solution['value2'],':') == true)
567 {
568 $current_solution = explode(':', $solution['value2']);
569
570 $user_order[$solution["value1"]]['index'] = $solution["value1"];
571 $user_order[$solution["value1"]]['random_id'] = $current_solution[0];
572 $user_order[$solution["value1"]]['depth'] = $current_solution[1];
573 // needed for graphical output
574 $answer_text = $this->object->lookupAnswerTextByRandomId($current_solution[0], $this->object->getId());
575 $user_order[$solution["value1"]]['answertext'] = $answer_text;
576 }
577 }
578 if( count($user_order) )
579 {
580 foreach($this->object->answers as $k => $a)
581 {
582 $ok = FALSE;
583 if($k == $user_order[$k]['index'] && $a->getOrderingDepth() == $user_order[$k]['depth'] && $a->getAnswerText() == $user_order[$k]['answertext'])
584 {
585 $ok = TRUE;
586
587 }
588 $user_order[$k]['ok'] = $ok;
589 }
590
591 $solution_output = $user_order;
592 }
593 else
594 {
595 $expected_solution = array();
596 foreach ($this->object->answers as $index => $answer)
597 {
598 $expected_solution[$index]['index'] = $index;
599 $expected_solution[$index]['random_id'] = $answer->getRandomId();
600 $expected_solution[$index]['depth'] = 0;
601 if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
602 {
603 $expected_solution[$index]['answertext'] = $answer->getAnswertext();
604 }
605 else
606 {
607 $expected_solution[$index]['answertext'] = $answer->getAnswertext();
608 }
609 }
610 shuffle($expected_solution);
611 $solution_output = $expected_solution;
612 }
613 }
614 else
615 {
616 foreach ($this->object->answers as $index => $answer)
617 {
618
619 $expected_solution[$index]['index'] = $index;
620 $expected_solution[$index]['random_id'] = $answer->getRandomId();
621 $expected_solution[$index]['depth'] = $answer->getOrderingDepth();
622 if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
623 {
624 $expected_solution[$index]['answertext'] = $answer->getAnswertext();
625 }
626 else
627 {
628 $expected_solution[$index]['answertext'] = $answer->getAnswertext();
629 }
630 }
631 $solution_output = $expected_solution;
632 }
633
634 include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
635 include_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
636
637 $answers_gui = new ilNestedOrderingGUI($this->lng->txt("answers"), "answers", $graphicalOutput);
638
639 $no_js_for_cmds = array('outParticipantsPassDetails', 'outCorrectSolution', 'showManScoringParticipantScreen');
640
641 //PERFORM_JAVASCRIPT
642 if(in_array($this->ctrl->getCmd(), $no_js_for_cmds))
643 {
644 $answers_gui->setPerformJavascript(false);
645 }
646 else
647 {
648 $answers_gui->setPerformJavascript(true);
649 }
650
651 $answers_gui->setOrderingType($this->object->getOrderingType());
652
653 if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
654 {
655 $answers_gui->setImagePath($this->object->getImagePath());
656 $answers_gui->setImagePathWeb($this->object->getImagePathWeb());
657 $answers_gui->setThumbPrefix($this->object->getThumbPrefix());
658 }
659
660 $solution_html = $answers_gui->getSolutionHTML($solution_output);
661
662 $template->setVariable('SOLUTION_OUTPUT', $solution_html);
663
664 $questiontext = $this->object->getQuestion();
665 if ($show_question_text==true)
666 {
667 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
668 }
669 $questionoutput = $template->get();
670
671 $feedback = '';
672 if($show_feedback)
673 {
674 if( !$this->isTestPresentationContext() )
675 {
676 $fb = $this->getGenericFeedbackOutput($active_id, $pass);
677 $feedback .= strlen($fb) ? $fb : '';
678 }
679
680 $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
681 $feedback .= strlen($fb) ? $fb : '';
682 }
683 if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
684
685 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
686
687 $solutionoutput = $solutiontemplate->get();
688 if (!$show_question_only)
689 {
690 // get page object output
691 $solutionoutput = $this->getILIASPage($solutionoutput);
692 }
693 }
694 else
695 {
696 $keys = array_keys($this->object->answers);
697
698 // generate the question output
699 include_once "./Services/UICore/classes/class.ilTemplate.php";
700 $template = new ilTemplate("tpl.il_as_qpl_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
701 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
702
703 // get the solution of the user for the active pass or from the last pass if allowed
704 $solutions = array();
705 if (($active_id > 0) && (!$show_correct_solution))
706 {
707 $solutions = $this->object->getSolutionValues($active_id, $pass);
708
709 if( !count($solutions) )
710 {
711 foreach ($this->object->answers as $index => $answer)
712 {
713 array_push($solutions, array("value1" => $index, "value2" => $index+1));
714 }
715
716 shuffle($keys);
717 }
718 }
719 else
720 {
721 foreach ($this->object->answers as $index => $answer)
722 {
723 array_push($solutions, array("value1" => $index, "value2" => $index+1));
724 }
725 }
726 foreach ($keys as $idx)
727 {
728 if (!$show_correct_solution)
729 {
730 foreach($solutions as $index => $item)
731 {
732 if($item['value2'] == $idx+1)
733 {
734 $answer = $this->object->answers[$item['value1']];
735 }
736 }
737 }
738 else
739 {
740 $answer = $this->object->answers[$idx];
741 }
742 if (!$answer)
743 {
744 continue;
745 }
746 if (($active_id > 0) && (!$show_correct_solution))
747 {
748 if ($graphicalOutput)
749 {
750 $sol = array();
751 foreach ($solutions as $solution)
752 {
753 $sol[$solution["value1"]] = $solution["value2"];
754 }
755 asort($sol);
756 $sol = array_keys($sol);
757 $ans = array();
758 foreach ($this->object->answers as $k => $a)
759 {
760 $ans[$k] = $k;
761 }
762 asort($ans);
763 $ans = array_keys($ans);
764 $ok = FALSE;
765 foreach ($ans as $arr_idx => $ans_idx)
766 {
767 if ($ans_idx == $idx)
768 {
769 if ($ans_idx == $sol[$arr_idx])
770 {
771 $ok = TRUE;
772 }
773 }
774 }
775 // output of ok/not ok icons for user entered solutions
776 if ($ok)
777 {
778 $template->setCurrentBlock("icon_ok");
779 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
780 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
781 $template->parseCurrentBlock();
782 }
783 else
784 {
785 $template->setCurrentBlock("icon_ok");
786 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
787 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
788 $template->parseCurrentBlock();
789 }
790 }
791 }
792 if ($this->object->getOrderingType() == OQ_PICTURES)
793 {
794 $template->setCurrentBlock("ordering_row_standard_pictures");
795 $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
796 $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
797 if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
798 $template->setVariable("THUMB_HREF", $thumbweb);
799 list($width, $height, $type, $attr) = getimagesize($thumb);
800 $template->setVariable("ATTR", $attr);
801 $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
802 $template->setVariable("THUMB_TITLE", $this->lng->txt("enlarge"));
803 $template->parseCurrentBlock();
804 }
805 else
806 {
807 $template->setCurrentBlock("ordering_row_standard_text");
808 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
809 $template->parseCurrentBlock();
810 }
811 $template->setCurrentBlock("ordering_row_standard");
812 if ($result_output)
813 {
814 $answer = $this->object->answers[$idx];
815 $points = $answer->getPoints();
816 $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
817 $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
818 }
819 foreach ($solutions as $solution)
820 {
821 if (strcmp($solution["value1"], $idx) == 0)
822 {
823 $template->setVariable("ANSWER_ORDER", $solution["value2"]);
824 }
825 }
826 $template->parseCurrentBlock();
827 }
828 $questiontext = $this->object->getQuestion();
829 if ($show_question_text==true)
830 {
831 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
832 }
833 $questionoutput = $template->get();
834 $feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
835 if (strlen($feedback))
836 {
837 $cssClass = ( $this->hasCorrectSolution($active_id, $pass) ?
839 );
840
841 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
842 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
843 }
844 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
845
846 $solutionoutput = $solutiontemplate->get();
847 if (!$show_question_only)
848 {
849 // get page object output
850 $solutionoutput = $this->getILIASPage($solutionoutput);
851 }
852 }
853
854 return $solutionoutput;
855 }
856
857 function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
858 {
859 global $tpl;
860
861 $this->object->setOutputType(OUTPUT_JAVASCRIPT);
862 $tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_javascript.css", "Modules/TestQuestionPool"));
863
864 include_once "./Services/UICore/classes/class.ilTemplate.php";
865 $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
866
867 if( is_object($this->getPreviewSession()) && count((array)$this->getPreviewSession()->getParticipantsSolution()) )
868 {
869 if ($this->object->getOrderingType() == OQ_NESTED_TERMS || $this->object->getOrderingType() == OQ_NESTED_PICTURES)
870 {
871 $answerMap = $this->getRandomIdToAnswerMap();
872
873 $answerArray = array();
874 $shuffleAnswers = false;
875
876 foreach((array)$this->getPreviewSession()->getParticipantsSolution() as $val1 => $val2)
877 {
878 list($randomId, $depth) = explode(':', $val2);
879
880 $answ = new ASS_AnswerOrdering(
881 $answerMap[$randomId]->getAnswertext(), $randomId, $depth
882 );
883
884 $answerArray[] = $answ;
885
886 $jssolutions[$val2] = $val1;
887 }
888 }
889 else
890 {
891 foreach((array)$this->getPreviewSession()->getParticipantsSolution() as $val1 => $val2)
892 {
893 $jssolutions[$val2] = $val1;
894 }
895 }
896 }
897 else
898 {
899 $answerArray = $this->object->answers;
900 $shuffleAnswers = true;
901 }
902
903
904 global $ilUser;
905
906 // shuffle output
907 $keys = array_keys($this->object->answers);
908 if($shuffleAnswers)
909 {
910 $keys = $this->object->getShuffler()->shuffle($keys);
911 }
912
913 if($GLOBALS['ilBrowser']->isMobile() || $GLOBALS['ilBrowser']->isIpad())
914 {
915 require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
918 $this->tpl->addJavaScript('./Services/jQuery/js/jquery.ui.touch-punch.min.js');
919 }
920
921 if ($this->object->getOrderingType() == OQ_NESTED_TERMS || $this->object->getOrderingType() == OQ_NESTED_PICTURES)
922 {
923 include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
924 include_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
925 $answers = new ilNestedOrderingGUI($this->lng->txt("answers"), "answers");
926 $answers->setOrderingType($this->object->getOrderingType());
927 $answers->setObjAnswersArray($answerArray, $shuffleAnswers);
928
929 if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
930 {
931 $answers->setImagePath($this->object->getImagePath());
932 $answers->setImagePathWeb($this->object->getImagePathWeb());
933 $answers->setThumbPrefix($this->object->getThumbPrefix());
934 }
935
936 $template->setCurrentBlock('nested_ordering_output');
937 $template->setVariable('NESTED_ORDERING',$answers->getHtml());
938 $template->parseCurrentBlock();
939 $questiontext = $this->object->getQuestion();
940 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
941 $questionoutput = $template->get();
942 if (!$show_question_only)
943 {
944 // get page object output
945 $questionoutput = $this->getILIASPage($questionoutput);
946 }
947 return $questionoutput;
948
949 }
950 else
951 {
952 $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/ordering.js");
953
954 $template->setCurrentBlock('form_submit_register');
955 $template->touchBlock('form_submit_register');
956 $template->parseCurrentBlock();
957
958 if(count($jssolutions))
959 {
960 ksort($jssolutions);
961 $initial_order = array();
962 foreach($jssolutions as $key => $value)
963 {
964 if(is_object($this->object->getAnswer($value)))
965 {
966 $initial_order[] = 'id_' . $this->object->getAnswer($value)->getRandomID();
967 }
968 }
969
970 $template->setVariable('INITIAL_ORDER', json_encode($initial_order));
971 }
972 else
973 {
974 $template->setVariable('INITIAL_ORDER', json_encode(array()));
975 }
976
977 foreach ($keys as $idx)
978 {
979 $answer = $this->object->answers[$idx];
980 if ($this->object->getOrderingType() == OQ_PICTURES)
981 {
982 $template->setCurrentBlock("ordering_row_javascript_pictures");
983 $template->setVariable("PICTURE_HREF", $this->object->getImagePathWeb() . $answer->getAnswertext());
984 $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
985 $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
986 if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
987 $template->setVariable("THUMB_HREF", $thumbweb);
988 $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
989 $template->setVariable("THUMB_TITLE", $this->lng->txt("thumbnail"));
990 $template->setVariable("ENLARGE_HREF", ilUtil::getImagePath("enlarge.svg", FALSE));
991 $template->setVariable("ENLARGE_ALT", $this->lng->txt("enlarge"));
992 $template->setVariable("ENLARGE_TITLE", $this->lng->txt("enlarge"));
993 $template->setVariable("ANSWER_ID", $answer->getRandomID());
994 $template->parseCurrentBlock();
995 }
996 else
997 {
998 $template->setCurrentBlock("ordering_row_javascript_text");
999 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
1000 $template->setVariable("ANSWER_ID", $answer->getRandomID());
1001 $template->parseCurrentBlock();
1002 }
1003 }
1004 if ($this->object->getOrderingType() == OQ_PICTURES)
1005 {
1006 $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_pictures"));
1007 }
1008 else
1009 {
1010 $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_definitions"));
1011 }
1012
1013 $questiontext = $this->object->getQuestion();
1014 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1015 $template->setVariable("QUESTION_ID", $this->object->getId());
1016 $questionoutput = $template->get();
1017 if (!$show_question_only)
1018 {
1019 // get page object output
1020 $questionoutput = $this->getILIASPage($questionoutput);
1021 }
1022 return $questionoutput;
1023 }
1024 }
1025
1026 private function getRandomIdToAnswerMap()
1027 {
1028 $randomIdToAnswerMap = array();
1029
1030 foreach($this->object->answers as $answer)
1031 {
1032 $randomIdToAnswerMap[$answer->getRandomId()] = $answer;
1033 }
1034
1035 return $randomIdToAnswerMap;
1036 }
1037
1038 // hey: prevPassSolutions - pass will be always available from now on
1039 function getTestOutput($active_id, $pass, $is_postponed = FALSE, $user_post_solution = FALSE, $inlineFeedback = false)
1040 // hey.
1041 {
1042 global $tpl;
1043
1044 $tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_javascript.css", "Modules/TestQuestionPool"));
1045
1046 // generate the question output
1047 include_once "./Services/UICore/classes/class.ilTemplate.php";
1048 $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
1049
1050 $this->object->setOutputType(OUTPUT_JAVASCRIPT);
1051 // shuffle output
1052 $keys = array();
1053 if (is_array($user_post_solution))
1054 {
1055 $keys = $_SESSION["ordering_keys"];
1056 }
1057 else
1058 {
1059 $keys = array_keys($this->object->answers);
1060 $keys = $this->object->getShuffler()->shuffle($keys);
1061 }
1062 $_SESSION["ordering_keys"] = $keys;
1063
1064 if($GLOBALS['ilBrowser']->isMobile() || $GLOBALS['ilBrowser']->isIpad())
1065 {
1066 require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
1069 $this->tpl->addJavaScript('./Services/jQuery/js/jquery.ui.touch-punch.min.js');
1070 }
1071
1072 if ($this->object->getOrderingType() == OQ_NESTED_TERMS
1073 || $this->object->getOrderingType() == OQ_NESTED_PICTURES)
1074 {
1075
1076 include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
1077 include_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
1078 $answerGUI = new ilNestedOrderingGUI($this->lng->txt("answers"), "answers");
1079 $answerGUI->setInstanceId('participant');
1080 $answerGUI->setOrderingType($this->object->getOrderingType());
1081
1082 $answerMap = $this->getRandomIdToAnswerMap();
1083
1084 $answerArray = array();
1085 $shuffleAnswers = false;
1086
1087 if( is_array($user_post_solution) && isset($user_post_solution['answers_ordering__participant']) )
1088 {
1089 $answers_ordering = $_POST['answers_ordering__participant'];
1090 $user_solution_hierarchy = json_decode($answers_ordering);
1091 $with_random_id = true;
1092 $this->object->setLeveledOrdering($user_solution_hierarchy, $with_random_id);
1093
1094 foreach($this->object->leveled_ordering as $randomId => $depth)
1095 {
1096 $answ = new ASS_AnswerOrdering(
1097 $answerMap[$randomId]->getAnswertext(), $randomId, $depth
1098 );
1099
1100 $answerArray[] = $answ;
1101 }
1102 }
1103 else
1104 {
1105 // hey: prevPassSolutions - obsolete due to central check
1106 #include_once "./Modules/Test/classes/class.ilObjTest.php";
1107
1108 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1109 #{
1110 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1111 #}
1112
1113 $solutions = $this->getTestOutputSolutions($active_id, $pass);
1114 // hey.
1115
1116 if( count($solutions) )
1117 {
1118 foreach($solutions as $solution)
1119 {
1120 list($randomId, $depth) = explode(':', $solution['value2']);
1121
1122 $answ = new ASS_AnswerOrdering(
1123 $answerMap[$randomId]->getAnswertext(), $randomId, $depth
1124 );
1125
1126 $answerArray[] = $answ;
1127 }
1128 }
1129 else
1130 {
1131 $answerArray = $this->object->answers;
1132 $shuffleAnswers = true;
1133 }
1134 }
1135
1136 $answerGUI->setObjAnswersArray($answerArray, $shuffleAnswers);
1137
1138 if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
1139 {
1140 $answerGUI->setImagePath($this->object->getImagePath());
1141 $answerGUI->setImagePathWeb($this->object->getImagePathWeb());
1142 $answerGUI->setThumbPrefix($this->object->getThumbPrefix());
1143 }
1144
1145 $template->setCurrentBlock('nested_ordering_output');
1146 $template->setVariable('NESTED_ORDERING',$answerGUI->getHtml($shuffleAnswers));
1147 $template->parseCurrentBlock();
1148 $questiontext = $this->object->getQuestion();
1149 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1150 $questionoutput = $template->get();
1151 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1152 return $pageoutput;
1153 }
1154 else
1155 {
1156 $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/ordering.js");
1157
1158 // BEGIN: onsubmit form action for javascript enabled ordering questions
1159 $this->tpl->setVariable("ON_SUBMIT", "return $('div.ilVerticalOrderingQuestion').ilOrderingQuestion('saveOrder');");
1160 // END: onsubmit form action for javascript enabled ordering questions
1161
1162 // get the solution of the user for the active pass or from the last pass if allowed
1163 if ($active_id)
1164 {
1165 // hey: prevPassSolutions - obsolete due to central check
1166 #$solutions = NULL;
1167 #include_once "./Modules/Test/classes/class.ilObjTest.php";
1168 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1169 #{
1170 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1171 #}
1172 // hey.
1173 if (is_array($user_post_solution))
1174 {
1175 $solutions = array();
1176 foreach ($user_post_solution as $key => $value)
1177 {
1178 if (preg_match("/order_(\d+)/", $key, $matches))
1179 {
1180 foreach ($this->object->getAnswers() as $answeridx => $answer)
1181 {
1182 if ($answer->getRandomID() == $matches[1])
1183 {
1184 array_push($solutions, array("value1" => $answeridx, "value2" => $value));
1185 }
1186 }
1187 }
1188 }
1189 }
1190 else
1191 {
1192 // hey: prevPassSolutions - obsolete due to central check
1193 $solutions = $this->getTestOutputSolutions($active_id, $pass);
1194 // hey.
1195 }
1196
1197 $jssolutions = array();
1198 foreach ($solutions as $idx => $solution_value)
1199 {
1200 if ((strcmp($solution_value["value2"], "") != 0) && (strcmp($solution_value["value1"], "") != 0))
1201 {
1202 $jssolutions[$solution_value["value2"]] = $solution_value["value1"];
1203 }
1204 }
1205 if(count($jssolutions))
1206 {
1207 ksort($jssolutions);
1208 $initial_order = array();
1209 foreach($jssolutions as $key => $value)
1210 {
1211 if(is_object($this->object->getAnswer($value)))
1212 {
1213 $initial_order[] = 'id_' . $this->object->getAnswer($value)->getRandomID();
1214 }
1215 }
1216
1217 $template->setVariable('INITIAL_ORDER', json_encode($initial_order));
1218 }
1219 else
1220 {
1221 $template->setVariable('INITIAL_ORDER', json_encode(array()));
1222 }
1223 }
1224
1225 foreach ($keys as $idx)
1226 {
1227 $answer = $this->object->answers[$idx];
1228 if ($this->object->getOrderingType() == OQ_PICTURES)
1229 {
1230 $template->setCurrentBlock("ordering_row_javascript_pictures");
1231 $template->setVariable("PICTURE_HREF", $this->object->getImagePathWeb() . $answer->getAnswertext());
1232 $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
1233 $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
1234 if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
1235 $template->setVariable("THUMB_HREF", $thumbweb);
1236 $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
1237 $template->setVariable("THUMB_TITLE", $this->lng->txt("thumbnail"));
1238 $template->setVariable("ENLARGE_HREF", ilUtil::getImagePath("enlarge.svg", FALSE));
1239 $template->setVariable("ENLARGE_ALT", $this->lng->txt("enlarge"));
1240 $template->setVariable("ENLARGE_TITLE", $this->lng->txt("enlarge"));
1241 $template->setVariable("ANSWER_ID", $answer->getRandomID());
1242 $template->parseCurrentBlock();
1243 }
1244 else
1245 {
1246 $template->setCurrentBlock("ordering_row_javascript_text");
1247 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
1248 $template->setVariable("ANSWER_ID", $answer->getRandomID());
1249 $template->parseCurrentBlock();
1250 }
1251 }
1252 if($this->object->getOrderingType() == OQ_PICTURES)
1253 {
1254 $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_pictures"));
1255 }
1256 else
1257 {
1258 $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_definitions"));
1259 }
1260
1261 $questiontext = $this->object->getQuestion();
1262 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1263 $template->setVariable("QUESTION_ID", $this->object->getId());
1264 $questionoutput = $template->get();
1265 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1266 $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/ordering.js");
1267 return $pageoutput;
1268 }
1269 }
1270
1279 {
1280 global $rbacsystem, $ilTabs;
1281
1282 $ilTabs->clearTargets();
1283
1284 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1285 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1286 $q_type = $this->object->getQuestionType();
1287
1288 if (strlen($q_type))
1289 {
1290 $classname = $q_type . "GUI";
1291 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1292 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1293 }
1294
1295 if ($_GET["q_id"])
1296 {
1297 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1298 {
1299 // edit page
1300 $ilTabs->addTarget("edit_page",
1301 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1302 array("edit", "insert", "exec_pg"),
1303 "", "", $force_active);
1304 }
1305
1306 $this->addTab_QuestionPreview($ilTabs);
1307 }
1308
1309 $force_active = false;
1310 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1311 {
1312 $url = "";
1313 if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1314 $commands = $_POST["cmd"];
1315 if (is_array($commands))
1316 {
1317 foreach ($commands as $key => $value)
1318 {
1319 if (preg_match("/^delete_.*/", $key, $matches))
1320 {
1321 $force_active = true;
1322 }
1323 }
1324 }
1325 // edit question properties
1326 $ilTabs->addTarget("edit_question",
1327 $url,
1328 array("orderNestedTerms","orderNestedPictures","editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "changeToPictures", "uploadanswers", "changeToText", "upanswers", "downanswers", "originalSyncForm"),
1329 $classname, "", $force_active);
1330 }
1331
1332 // add tab for question feedback within common class assQuestionGUI
1333 $this->addTab_QuestionFeedback($ilTabs);
1334
1335 // add tab for question hint within common class assQuestionGUI
1336 $this->addTab_QuestionHints($ilTabs);
1337
1338 // add tab for question's suggested solution within common class assQuestionGUI
1339 $this->addTab_SuggestedSolution($ilTabs, $classname);
1340
1341 // Assessment of questions sub menu entry
1342 if ($_GET["q_id"])
1343 {
1344 $ilTabs->addTarget("statistics",
1345 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1346 array("assessment"),
1347 $classname, "");
1348 }
1349
1350 $this->addBackTab($ilTabs);
1351 }
1352
1353 function getSpecificFeedbackOutput($active_id, $pass)
1354 {
1355 if( !$this->object->feedbackOBJ->specificAnswerFeedbackExists($this->object->getAnswers()) )
1356 {
1357 return '';
1358 }
1359
1360 $output = '<table class="test_specific_feedback"><tbody>';
1361
1362 foreach($this->object->getAnswers() as $idx => $answer)
1363 {
1364 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
1365 $this->object->getId(), $idx
1366 );
1367
1368 $output .= "<tr><td>{$answer->getAnswerText()}</td><td>{$feedback}</td></tr>";
1369 }
1370
1371 $output .= '</tbody></table>';
1372
1373 return $this->object->prepareTextareaOutput($output, TRUE);
1374 }
1375
1376 private function getDepthRecursive($child, $ordering_depth)
1377 {
1378 if(is_array($child->children))
1379 {
1380 foreach($child->children as $grand_child)
1381 {
1382 $ordering_depth++;
1383 $this->leveled_ordering[] = $ordering_depth;
1384 $this->getDepthRecursive($grand_child, $ordering_depth);
1385 }
1386 }
1387 else
1388 {
1389 $ordering_depth++;
1390 $this->leveled_ordering[] = $ordering_depth;
1391 }
1392 }
1393
1394 public function setLeveledOrdering($new_hierarchy)
1395 {
1396 foreach($new_hierarchy as $id)
1397 {
1398 $ordering_depth = 0;
1399 $this->leveled_ordering[] = $ordering_depth;
1400
1401 if(is_array($id->children))
1402 {
1403 foreach($id->children as $child)
1404 {
1405 $this->getDepthRecursive($child, $ordering_depth);
1406 }
1407 }
1408 }
1409 }
1410
1411 private function getOldLeveledOrdering()
1412 {
1413 global $ilDB;
1414
1415 $res = $ilDB->queryF('SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_order ASC',
1416 array('integer'), array($this->object->getId()));
1417 while($row = $ilDB->fetchAssoc($res))
1418 {
1419 $this->old_ordering_depth[] = $row['depth'];
1420 }
1422 }
1423
1434 {
1435 return array();
1436 }
1437
1448 {
1449 return array();
1450 }
1451
1460 public function getAggregatedAnswersView($relevant_answers)
1461 {
1462 return $this->renderAggregateView(
1463 $this->aggregateAnswers( $relevant_answers, $this->object->getAnswers() ) )->get();
1464 }
1465
1466 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
1467 {
1468 $passdata = array(); // Regroup answers into units of passes.
1469 foreach($relevant_answers_chosen as $answer_chosen)
1470 {
1471 $passdata[$answer_chosen['active_fi'].'-'. $answer_chosen['pass']][$answer_chosen['value2']] = $answer_chosen['value1'];
1472 }
1473
1474 $variants = array(); // Determine unique variants.
1475 foreach($passdata as $key => $data)
1476 {
1477 $hash = md5(implode('-', $data));
1478 $value_set = false;
1479 foreach ($variants as $vkey => $variant)
1480 {
1481 if ($variant['hash'] == $hash)
1482 {
1483 $variant['count']++;
1484 $value_set = true;
1485 }
1486 }
1487 if (!$value_set)
1488 {
1489 $variants[$key]['hash'] = $hash;
1490 $variants[$key]['count'] = 1;
1491 }
1492 }
1493
1494 $aggregate = array(); // Render aggregate from variant.
1495 foreach ($variants as $key => $variant_entry)
1496 {
1497 $variant = $passdata[$key];
1498
1499 foreach($variant as $variant_key => $variant_line)
1500 {
1501 $i = 0;
1502 $aggregated_info_for_answer['count'] = $variant_entry['count'];
1503 foreach ($answers_defined_on_question as $answer)
1504 {
1505 $i++;
1506 $aggregated_info_for_answer[$i . ' - ' . $answer->getAnswerText()]
1507 = $passdata[$key][$i];
1508 }
1509
1510 }
1511 $aggregate[] = $aggregated_info_for_answer;
1512 }
1513 return $aggregate;
1514 }
1515
1521 public function renderAggregateView($aggregate)
1522 {
1523 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
1524
1525 foreach ($aggregate as $line_data)
1526 {
1527 $tpl->setCurrentBlock( 'aggregaterow' );
1528 $count = array_shift($line_data);
1529 $html = '<ul>';
1530 foreach($line_data as $key => $line)
1531 {
1532 $html .= '<li>'. ++$line .'&nbsp;-&nbsp;' .$key. '</li>';
1533 }
1534 $html .= '</ul>';
1535 $tpl->setVariable( 'COUNT', $count );
1536 $tpl->setVariable( 'OPTION', $html );
1537
1538 $tpl->parseCurrentBlock();
1539 }
1540 return $tpl;
1541 }
1542}
$filename
Definition: buildRTE.php:89
$_GET["client_id"]
$_SESSION["AccountId"]
Class for ordering question answers.
Ordering question GUI representation.
getDepthRecursive($child, $ordering_depth)
setQuestionTabs()
Sets the ILIAS tabs for this question type.
__construct($id=-1)
assOrderingQuestionGUI constructor
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.
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
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.
getSpecificFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
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.
setClearAnswersOnWritingPostDataEnabled($clearAnswersOnWritingPostDataEnabled)
populateCommandButtons(ilPropertyFormGUI $form)
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getTestOutput($active_id, $pass, $is_postponed=FALSE, $user_post_solution=FALSE, $inlineFeedback=false)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
Class for ordering questions.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
writePostData()
Evaluates a posted edit form and writes the form data in the question object.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
getTestOutputSolutions($activeId, $pass)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
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)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
This class represents a section header in a property form.
This class represents a single choice wizard property 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).
addCommandButton($a_cmd, $a_text)
Add Command button.
special template class to simplify handling of ITX/PEAR
This class represents a text wizard property in a property form.
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static initjQueryUI()
Init jQuery UI (see included_components.txt for included components)
static initjQuery($a_tpl=null)
Init jQuery.
$_POST['username']
Definition: cron.php:12
$html
Definition: example_001.php:87
$header
$data
$GLOBALS['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276
const OQ_NESTED_PICTURES
const OUTPUT_JAVASCRIPT
const OQ_TERMS
const OQ_NESTED_TERMS
const OQ_PICTURES
Ordering question constants.
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$url
Definition: shib_logout.php:72
global $ilDB
$errors
global $ilUser
Definition: imgupload.php:15