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 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5 require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7 require_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';
441  $this->saveTaxonomyAssignments();
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 );
467  $this->populateQuestionSpecificFormPart($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 
512  case OQ_NESTED_PICTURES:
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 
1278  function setQuestionTabs()
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 }
__construct($id=-1)
assOrderingQuestionGUI constructor
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
static initjQueryUI()
Init jQuery UI (see included_components.txt for included components)
getTestOutput($active_id, $pass, $is_postponed=FALSE, $user_post_solution=FALSE, $inlineFeedback=false)
getSolutionOutput( $active_id, $pass=NULL, $graphicalOutput=FALSE, $result_output=FALSE, $show_question_only=TRUE, $show_feedback=FALSE, $show_correct_solution=FALSE, $show_manual_scoring=FALSE, $show_question_text=TRUE)
Get the question solution output.
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
writePostData()
Evaluates a posted edit form and writes the form data in the question object.
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
$_POST['username']
Definition: cron.php:12
setValue($a_value)
Set Value.
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
$_SESSION["AccountId"]
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
This class represents a property form user interface.
Class for ordering question answers.
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
$_GET["client_id"]
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
Adds the answer specific form parts to a question property form gui.
This class represents a section header in a property form.
const OQ_NESTED_TERMS
getTestOutputSolutions($activeId, $pass)
This class represents a single choice wizard property in a property form.
addItem($a_item)
Add Item (Property, SectionHeader).
$url
Definition: shib_logout.php:72
getQuestionTemplate()
get question template
const OUTPUT_JAVASCRIPT
populateTaxonomyFormSection(ilPropertyFormGUI $form)
setClearAnswersOnWritingPostDataEnabled($clearAnswersOnWritingPostDataEnabled)
allowDecimals($a_value)
Toggle Decimals.
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
populateCommandButtons(ilPropertyFormGUI $form)
$data
const OQ_PICTURES
Ordering question constants.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
$header
getILIASPage($html="")
Returns the ILIAS Page around a question.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
This class represents a number property in a property form.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
special template class to simplify handling of ITX/PEAR
Ordering question GUI representation.
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
Basic GUI class for assessment questions.
addCommandButton($a_cmd, $a_text)
Add Command button.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
setOrderingType($a_ordering_type)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$filename
Definition: buildRTE.php:89
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
$errors
const OQ_TERMS
global $ilUser
Definition: imgupload.php:15
getDepthRecursive($child, $ordering_depth)
const OQ_NESTED_PICTURES
addBackTab(ilTabsGUI $ilTabs)
global $ilDB
Class for ordering questions.
static initjQuery($a_tpl=null)
Init jQuery.
Interface ilGuiAnswerScoringAdjustable.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
This class represents a text wizard property in a property form.
$GLOBALS['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
Interface ilGuiQuestionScoringAdjustable.
$html
Definition: example_001.php:87
setRequired($a_required)
Set Required.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.