ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
38  public function __construct($id = -1)
39  {
41  include_once "./Modules/TestQuestionPool/classes/class.assOrderingQuestion.php";
42  $this->object = new assOrderingQuestion();
43  if ($id >= 0)
44  {
45  $this->object->loadFromDb($id);
46  }
47  $this->object->setOutputType(OUTPUT_JAVASCRIPT);
48  }
49 
50  public function changeToPictures()
51  {
52  if($this->object->getOrderingType() != OQ_NESTED_PICTURES && $this->object->getOrderingType() != OQ_PICTURES)
53  {
54  $clearAnswers = true;
55  }
56  else
57  {
58  $clearAnswers = false;
59  }
60 
61  $this->object->setOrderingType(OQ_PICTURES);
62  $this->writePostData(true, $clearAnswers);
63  $this->object->saveToDb();
64 
65  $this->editQuestion();
66  }
67 
68  public function changeToText()
69  {
70  if($this->object->getOrderingType() != OQ_NESTED_TERMS && $this->object->getOrderingType() != OQ_TERMS)
71  {
72  $clearAnswers = true;
73  }
74  else
75  {
76  $clearAnswers = false;
77  }
78 
79  $this->object->setOrderingType(OQ_TERMS);
80  $this->writePostData(true, $clearAnswers);
81  $this->object->saveToDb();
82 
83  $this->editQuestion();
84  }
85 
86  public function orderNestedTerms()
87  {
88  if($this->object->getOrderingType() != OQ_NESTED_TERMS && $this->object->getOrderingType() != OQ_TERMS)
89  {
90  $clearAnswers = true;
91  }
92  else
93  {
94  $clearAnswers = false;
95  }
96 
97  $this->object->setOrderingType(OQ_NESTED_TERMS);
98  $this->writePostData(true, $clearAnswers);
99  $this->object->saveToDb();
100 
101  $this->editQuestion();
102  }
103 
104  public function orderNestedPictures()
105  {
106  $this->object->setOrderingType(OQ_NESTED_PICTURES);
107  $this->writePostData(true);
108  $this->object->saveToDb();
109 
110  $this->editQuestion();
111  }
112 
113  public function addanswers()
114  {
115  $this->writePostData(true);
116  $position = key($_POST["cmd"]["addanswers"]);
117  $this->object->addAnswer("", $position+1);
118  $this->editQuestion();
119  }
120 
121  public function removeimageanswers()
122  {
123  $this->writePostData(true);
124  $position = key($_POST['cmd']['removeimageanswers']);
125  $filename = $_POST['answers']['imagename'][$position];
126  $this->object->removeAnswerImage($position);
127  $this->editQuestion();
128  }
129 
130  public function removeanswers()
131  {
132  $this->writePostData(true);
133  $position = key($_POST["cmd"]["removeanswers"]);
134  $this->object->deleteAnswer($position);
135  $this->editQuestion();
136  }
137 
138  public function upanswers()
139  {
140  $this->writePostData(true);
141  $position = key($_POST["cmd"]["upanswers"]);
142  $this->object->moveAnswerUp($position);
143  $this->editQuestion();
144  }
145 
146  public function downanswers()
147  {
148  $this->writePostData(true);
149  $position = key($_POST["cmd"]["downanswers"]);
150  $this->object->moveAnswerDown($position);
151  $this->editQuestion();
152  }
153 
158  {
159  include_once "./Modules/TestQuestionPool/classes/class.ilImageWizardInputGUI.php";
160  $answers = new ilImageWizardInputGUI($this->lng->txt("answers"), "answers");
161  $answers->setRequired(TRUE);
162  $answers->setQuestionObject($this->object);
163  $answers->setInfo($this->lng->txt('ordering_answer_sequence_info'));
164  $answers->setAllowMove(TRUE);
165  $answervalues = array();
166  foreach ($this->object->getAnswers() as $index => $answervalue)
167  {
168  $answervalues[$index] = $answervalue->getAnswertext();
169  }
170  $answers->setValues($answervalues);
171  return $answers;
172  }
173 
174  public function uploadanswers()
175  {
176  $this->lng->loadLanguageModule('form');
177 
179 
180  if( !$inp->checkInput() )
181  {
182  $this->uploadAlert = $inp->getAlert();
183  ilUtil::sendFailure($inp->getAlert());
184  }
185 
186  $this->writePostData(true);
187  $this->editQuestion();
188  }
189 
190  public function writeQuestionSpecificPostData($always = true)
191  {
192  $this->object->setThumbGeometry( $_POST["thumb_geometry"] );
193  $this->object->setElementHeight( $_POST["element_height"] );
194  //$this->object->setOrderingType( $_POST["ordering_type"] );
195  $this->object->setPoints($_POST["points"]);
196  }
197 
198  public function writeAnswerSpecificPostData($clear_answers = false)
199  {
200  $ordering_type = $this->object->getOrderingType();
201  // Delete all existing answers and create new answers from the form data
202  $this->object->flushAnswers();
203  $saved = false;
204 
205  // add answers
206  if ($ordering_type == OQ_TERMS
207  || $ordering_type == OQ_NESTED_TERMS
208  || $ordering_type == OQ_NESTED_PICTURES
209  )
210  {
211  $answers = $_POST["answers"];
212  if (is_array( $answers ))
213  {
215  $answers_ordering = $_POST['answers_ordering__default']; // __default is added by js
216  $new_hierarchy = json_decode( $answers_ordering );
217 
218  $this->getOldLeveledOrdering();
219 
220  if (!is_array( $new_hierarchy ))
221  {
222  $this->leveled_ordering = $this->old_ordering_depth;
223  }
224  else
225  {
226  $this->setLeveledOrdering( $new_hierarchy );
227  }
228 
229  $counter = 0;
230 
231  if(is_array($answers['imagename']))
232  {
233  foreach($answers['imagename'] as $index => $answer)
234  {
235  if($clear_answers)
236  {
237  $answer = "";
238  }
239  $this->object->addAnswer($answer, -1, $this->leveled_ordering[$counter]);
240  $counter++;
241  }
242  }
243  else
244  {
245  foreach($answers as $index => $answer)
246  {
247  if($clear_answers)
248  {
249  $answer = "";
250  }
251  $this->object->addAnswer($answer, -1, $this->leveled_ordering[$counter]);
252  $counter++;
253  }
254  }
255  }
256  }
257  else
258  {
259  if (is_array( $_POST['answers']['count'] ))
260  {
261  foreach (array_keys( $_POST['answers']['count'] ) as $index)
262  {
263  if ($clear_answers)
264  {
265  $this->object->addAnswer( "" );
266  continue;
267  }
268 
269  $picturefile = $_POST['answers']['imagename'][$index];
270  $file_org_name = $_FILES['answers']['name']['image'][$index];
271  $file_temp_name = $_FILES['answers']['tmp_name']['image'][$index];
272 
273  // new file
274  if (strlen( $file_temp_name ))
275  {
276  // check suffix
277  $suffix = strtolower( array_pop( explode( ".", $file_org_name ) ) );
278  if (in_array( $suffix, array( "jpg", "jpeg", "png", "gif" ) ))
279  {
280  // upload image
281  $filename = $this->object->createNewImageFileName( $file_org_name );
282  $filename = $this->object->getEncryptedFilename( $filename );
283  if ($this->object->setImageFile( $file_temp_name, $filename, $picturefile ))
284  {
285  $picturefile = $filename;
286  }
287  }
288  }
289 
290  $this->object->addAnswer( $picturefile );
291  }
292  }
293  else if(is_array($_POST['answers']))
294  {
295  foreach($_POST['answers'] as $random_id => $text_value)
296  {
297  $this->object->addAnswer( $text_value );
298  }
299  }
300  }
301  }
302 
304  {
305  $orderingtype = $this->object->getOrderingType();
306 
307  if (count($this->object->getAnswers()) == 0)
308  {
309  $this->object->addAnswer();
310  }
311 
312  $header = new ilFormSectionHeaderGUI();
313  $header->setTitle($this->lng->txt('oq_header_ordering_elements'));
314  $form->addItem($header);
315 
316  if ($orderingtype == OQ_PICTURES)
317  {
318  $answerImageUpload = $this->getAnswerImageFileUploadWizardFormProperty();
319  if ($this->uploadAlert !== null)
320  {
321  $answerImageUpload->setAlert( $this->uploadAlert );
322  }
323  $form->addItem( $answerImageUpload );
324  }
325  else if ($orderingtype == OQ_NESTED_TERMS || $orderingtype == OQ_NESTED_PICTURES)
326  {
327  require_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
328  $answers = new ilNestedOrderingGUI($this->lng->txt( "answers" ), "answers");
329  $answers->setOrderingType( $orderingtype );
330  $answers->setObjAnswersArray( $this->object->getAnswers() );
331 
332  if ($orderingtype == OQ_NESTED_PICTURES)
333  {
334  $answers->setImagePath( $this->object->getImagePath() );
335  $answers->setImagePathWeb( $this->object->getImagePathWeb() );
336  $answers->setThumbPrefix( $this->object->getThumbPrefix() );
337  }
338  $answers->setInfo( $this->lng->txt( 'ordering_answer_sequence_info' ) );
339  $form->addItem( $answers );
340  }
341  else
342  {
343  require_once './Modules/TestQuestionPool/classes/class.ilOrderingTextWizardInputGUI.php';
344  $answers = new ilOrderingTextWizardInputGUI($this->lng->txt( "answers" ), "answers");
345  $answervalues = array();
346  foreach ($this->object->getAnswers() as $index => $answervalue)
347  {
348  $answervalues[$index] = $answervalue->getAnswertext();
349  }
350  ksort( $answervalues );
351  $answers->setValues( $answervalues );
352  $answers->setAllowMove( TRUE );
353  $answers->setRequired( TRUE );
354 
355  $answers->setInfo( $this->lng->txt( 'ordering_answer_sequence_info' ) );
356  $form->addItem( $answers );
357  }
358 
359  return $form;
360  }
361 
362  public function reworkFormForCorrectionMode(ilPropertyFormGUI $form)
363  {
364  $wizard_gui = $form->getItemByPostVar('answers');
365 
366  if($wizard_gui instanceof ilOrderingTextWizardInputGUI)
367  {
369  $wizard_gui->setDisableActions( true );
370  $wizard_gui->setDisableText( true );
371  }
372 
373  if($wizard_gui instanceof ilImageWizardInputGUI)
374  {
376  $wizard_gui->setDisableActions(true);
377  $wizard_gui->setDisableUpload(true);
378  }
379 
380  if($wizard_gui instanceof ilNestedOrderingGUI)
381  {
383  $wizard_gui->setDisabled(true);
384  }
385  return $form;
386  }
387 
389  {
390  $orderingtype = $this->object->getOrderingType();
391 
392  // Edit mode
393 
394  //$hidden = new ilHiddenInputGUI("ordering_type");
395  //$hidden->setValue( $orderingtype );
396  //$form->addItem( $hidden );
397 
398  if (!$this->object->getSelfAssessmentEditingMode())
399  {
400  $element_height = new ilNumberInputGUI($this->lng->txt( "element_height" ), "element_height");
401  $element_height->setValue( $this->object->getElementHeight() );
402  $element_height->setRequired( false );
403  $element_height->setMaxLength( 6 );
404  $element_height->setMinValue( 20 );
405  $element_height->setSize( 6 );
406  $element_height->setInfo( $this->lng->txt( "element_height_info" ) );
407  $form->addItem( $element_height );
408  }
409 
410  if ($orderingtype == OQ_PICTURES)
411  {
412  $geometry = new ilNumberInputGUI($this->lng->txt( "thumb_geometry" ), "thumb_geometry");
413  $geometry->setValue( $this->object->getThumbGeometry() );
414  $geometry->setRequired( true );
415  $geometry->setMaxLength( 6 );
416  $geometry->setMinValue( 20 );
417  $geometry->setSize( 6 );
418  $geometry->setInfo( $this->lng->txt( "thumb_geometry_info" ) );
419  $form->addItem( $geometry );
420  }
421 
422  // points
423  $points = new ilNumberInputGUI($this->lng->txt( "points" ), "points");
424  $points->allowDecimals( true );
425  $points->setValue( $this->object->getPoints() );
426  $points->setRequired( TRUE );
427  $points->setSize( 3 );
428  $points->setMinValue( 0 );
429  $points->setMinvalueShouldBeGreater( true );
430  $form->addItem( $points );
431 
432  return $form;
433  }
434 
435  private function isUploadAnswersCommand()
436  {
437  return $this->ctrl->getCmd() == 'uploadanswers';
438  }
439 
448  public function writePostData($always = false, $clear_answers = false)
449  {
450  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
451  if (!$hasErrors)
452  {
455  $this->writeAnswerSpecificPostData( $clear_answers );
456  $this->saveTaxonomyAssignments();
457  return 0;
458  }
459 
460  return 1;
461  }
462 
466  public function editQuestion($checkonly = FALSE)
467  {
468  $save = $this->isSaveCommand();
469  $this->getQuestionTemplate();
470 
471  $orderingtype = $this->object->getOrderingType();
472 
473  require_once "./Services/Form/classes/class.ilPropertyFormGUI.php";
474  $form = new ilPropertyFormGUI();
475  $form->setFormAction($this->ctrl->getFormAction($this));
476  $form->setTitle($this->outQuestionType());
477  $form->setMultipart(($orderingtype == OQ_PICTURES) ? TRUE : FALSE);
478  $form->setTableWidth("100%");
479  $form->setId("ordering");
480  // title, author, description, question, working time (assessment mode)
481  $this->addBasicQuestionFormProperties( $form );
482  $this->populateQuestionSpecificFormPart($form );
483  $this->populateAnswerSpecificFormPart( $form );
484 
485  if (true || !$this->object->getSelfAssessmentEditingMode())
486  {
487  $this->populateCommandButtons($form);
488  }
489 
490  $this->populateTaxonomyFormSection($form);
491  $this->addQuestionFormCommandButtons($form);
492  $errors = false;
493  if ($save)
494  {
495  $form->setValuesByPost();
496  $errors = !$form->checkInput();
497  $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
498  if ($errors) $checkonly = false;
499  }
500 
501  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
502  return $errors;
503  }
504 
506  {
507  switch( $this->object->getOrderingType() )
508  {
509  case OQ_TERMS:
510 
511  $form->addCommandButton("changeToPictures", $this->lng->txt("oq_btn_use_order_pictures"));
512  $form->addCommandButton("orderNestedTerms", $this->lng->txt("oq_btn_nest_terms"));
513  break;
514 
515  case OQ_PICTURES:
516 
517  $form->addCommandButton("changeToText", $this->lng->txt("oq_btn_use_order_terms"));
518  $form->addCommandButton("orderNestedPictures", $this->lng->txt("oq_btn_nest_pictures"));
519  break;
520 
521  case OQ_NESTED_TERMS:
522 
523  $form->addCommandButton("changeToPictures", $this->lng->txt("oq_btn_use_order_pictures"));
524  $form->addCommandButton("changeToText", $this->lng->txt("oq_btn_define_terms"));
525  break;
526 
527  case OQ_NESTED_PICTURES:
528 
529  $form->addCommandButton("changeToText", $this->lng->txt("oq_btn_use_order_terms"));
530  $form->addCommandButton("changeToPictures", $this->lng->txt("oq_btn_define_pictures"));
531  break;
532  }
533  }
534 
535  function outQuestionForTest($formaction, $active_id, $pass = NULL, $is_postponed = FALSE, $user_post_solution = FALSE)
536  {
537  $test_output = $this->getTestOutput($active_id, $pass, $is_postponed, $user_post_solution);
538  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
539  $this->tpl->setVariable("FORMACTION", $formaction);
540  }
541 
558  $active_id,
559  $pass = NULL,
560  $graphicalOutput = FALSE,
561  $result_output = FALSE,
562  $show_question_only = TRUE,
563  $show_feedback = FALSE,
564  $show_correct_solution = FALSE,
565  $show_manual_scoring = FALSE,
566  $show_question_text = TRUE
567  )
568  {
569  if($this->object->getOrderingType() == OQ_NESTED_TERMS
570  || $this->object->getOrderingType() == OQ_NESTED_PICTURES)
571  {
572  $keys = array_keys($this->object->answers);
573 
574  // generate the question output
575  include_once "./Services/UICore/classes/class.ilTemplate.php";
576  $template = new ilTemplate("tpl.il_as_qpl_nested_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
577 
578  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
579 
580  // get the solution of the user for the active pass or from the last pass if allowed
581  $solutions = array();
582 
583  if (($active_id > 0) && (!$show_correct_solution))
584  {
585  $solutions = $this->object->getSolutionValues($active_id, $pass);
586  $user_order = array();
587  foreach ($solutions as $solution)
588  {
589  if(strchr( $solution['value2'],':') == true)
590  {
591  $current_solution = explode(':', $solution['value2']);
592 
593  $user_order[$solution["value1"]]['index'] = $solution["value1"];
594  $user_order[$solution["value1"]]['random_id'] = $current_solution[0];
595  $user_order[$solution["value1"]]['depth'] = $current_solution[1];
596  // needed for graphical output
597  $answer_text = $this->object->lookupAnswerTextByRandomId($current_solution[0]);
598  $user_order[$solution["value1"]]['answertext'] = $answer_text;
599  }
600  }
601  foreach ($this->object->answers as $k => $a)
602  {
603  $ok = FALSE;
604  if ($k == $user_order[$k]['index']
605  && $a->getOrderingDepth() == $user_order[$k]['depth']
606  && $a->getAnswerText() == $user_order[$k]['answertext'])
607  {
608  $ok = TRUE;
609 
610  }
611  $user_order[$k]['ok'] = $ok;
612  }
613 
614  $solution_output = $user_order;
615  }
616  else
617  {
618  foreach ($this->object->answers as $index => $answer)
619  {
620 
621  $expected_solution[$index]['index'] = $index;
622  $expected_solution[$index]['random_id'] = $answer->getRandomId();
623  $expected_solution[$index]['depth'] = $answer->getOrderingDepth();
624  if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
625  {
626  $expected_solution[$index]['answertext'] = $answer->getAnswertext();
627  }
628  else
629  {
630  $expected_solution[$index]['answertext'] = $answer->getAnswertext();
631  }
632  }
633  $solution_output = $expected_solution;
634  }
635 
636  include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
637  include_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
638 
639  $answers_gui = new ilNestedOrderingGUI($this->lng->txt("answers"), "answers", $graphicalOutput);
640 
641  $no_js_for_cmds = array('outParticipantsPassDetails', 'outCorrectSolution', 'showManScoringParticipantScreen');
642 
643  //PERFORM_JAVASCRIPT
644  if(in_array($this->ctrl->getCmd(), $no_js_for_cmds))
645  {
646  $answers_gui->setPerformJavascript(false);
647  }
648  else
649  {
650  $answers_gui->setPerformJavascript(true);
651  }
652 
653  $answers_gui->setOrderingType($this->object->getOrderingType());
654 
655  if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
656  {
657  $answers_gui->setImagePath($this->object->getImagePath());
658  $answers_gui->setImagePathWeb($this->object->getImagePathWeb());
659  $answers_gui->setThumbPrefix($this->object->getThumbPrefix());
660  }
661 
662  $solution_html = $answers_gui->getSolutionHTML($solution_output);
663 
664  $template->setVariable('SOLUTION_OUTPUT', $solution_html);
665 
666  $questiontext = $this->object->getQuestion();
667  if ($show_question_text==true)
668  {
669  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
670  }
671  $questionoutput = $template->get();
672 
673  $feedback = '';
674  if($show_feedback)
675  {
676  $fb = $this->getGenericFeedbackOutput($active_id, $pass);
677  $feedback .= strlen($fb) ? $fb : '';
678 
679  $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
680  $feedback .= strlen($fb) ? $fb : '';
681  }
682  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
683 
684  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
685 
686  $solutionoutput = $solutiontemplate->get();
687  if (!$show_question_only)
688  {
689  // get page object output
690  $solutionoutput = $this->getILIASPage($solutionoutput);
691  }
692 
693  return $solutionoutput;
694  }
695  else
696  {
697  $keys = array_keys($this->object->answers);
698 
699  // generate the question output
700  include_once "./Services/UICore/classes/class.ilTemplate.php";
701  $template = new ilTemplate("tpl.il_as_qpl_ordering_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
702  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
703 
704  // get the solution of the user for the active pass or from the last pass if allowed
705  $solutions = array();
706  if (($active_id > 0) && (!$show_correct_solution))
707  {
708  $solutions = $this->object->getSolutionValues($active_id, $pass);
709  }
710  else
711  {
712  foreach ($this->object->answers as $index => $answer)
713  {
714  array_push($solutions, array("value1" => $index, "value2" => $index+1));
715  }
716  }
717  foreach ($keys as $idx)
718  {
719  if (!$show_correct_solution)
720  {
721  foreach($solutions as $index => $item)
722  {
723  if($item['value2'] == $idx+1)
724  {
725  $answer = $this->object->answers[$item['value1']];
726  }
727  }
728  }
729  else
730  {
731  $answer = $this->object->answers[$idx];
732  }
733  if (!$answer)
734  {
735  continue;
736  }
737  if (($active_id > 0) && (!$show_correct_solution))
738  {
739  if ($graphicalOutput)
740  {
741  $sol = array();
742  foreach ($solutions as $solution)
743  {
744  $sol[$solution["value1"]] = $solution["value2"];
745  }
746  asort($sol);
747  $sol = array_keys($sol);
748  $ans = array();
749  foreach ($this->object->answers as $k => $a)
750  {
751  $ans[$k] = $k;
752  }
753  asort($ans);
754  $ans = array_keys($ans);
755  $ok = FALSE;
756  foreach ($ans as $arr_idx => $ans_idx)
757  {
758  if ($ans_idx == $idx)
759  {
760  if ($ans_idx == $sol[$arr_idx])
761  {
762  $ok = TRUE;
763  }
764  }
765  }
766  // output of ok/not ok icons for user entered solutions
767  if ($ok)
768  {
769  $template->setCurrentBlock("icon_ok");
770  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.png"));
771  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
772  $template->parseCurrentBlock();
773  }
774  else
775  {
776  $template->setCurrentBlock("icon_ok");
777  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.png"));
778  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
779  $template->parseCurrentBlock();
780  }
781  }
782  }
783  if ($this->object->getOrderingType() == OQ_PICTURES)
784  {
785  $template->setCurrentBlock("ordering_row_standard_pictures");
786  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
787  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
788  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
789  $template->setVariable("THUMB_HREF", $thumbweb);
790  list($width, $height, $type, $attr) = getimagesize($thumb);
791  $template->setVariable("ATTR", $attr);
792  $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
793  $template->setVariable("THUMB_TITLE", $this->lng->txt("enlarge"));
794  $template->parseCurrentBlock();
795  }
796  else
797  {
798  $template->setCurrentBlock("ordering_row_standard_text");
799  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
800  $template->parseCurrentBlock();
801  }
802  $template->setCurrentBlock("ordering_row_standard");
803  if ($result_output)
804  {
805  $answer = $this->object->answers[$idx];
806  $points = $answer->getPoints();
807  $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
808  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
809  }
810  foreach ($solutions as $solution)
811  {
812  if (strcmp($solution["value1"], $idx) == 0)
813  {
814  $template->setVariable("ANSWER_ORDER", $solution["value2"]);
815  }
816  }
817  $template->parseCurrentBlock();
818  }
819  $questiontext = $this->object->getQuestion();
820  if ($show_question_text==true)
821  {
822  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
823  }
824  $questionoutput = $template->get();
825  $feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
826  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
827  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
828 
829  $solutionoutput = $solutiontemplate->get();
830  if (!$show_question_only)
831  {
832  // get page object output
833 // $solutionoutput = $this->getILIASPage($solutionoutput);
834  $solutionoutput = '<div class="ilc_question_Standard">'.$solutionoutput."</div>";
835  }
836  return $solutionoutput;
837  }
838  }
839 
840  function getPreview($show_question_only = FALSE)
841  {
842  global $ilUser;
843 
844  // shuffle output
845  $keys = array_keys($this->object->answers);
846  shuffle($keys);
847 
848  // generate the question output
849  include_once "./Services/UICore/classes/class.ilTemplate.php";
850  $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
851  if ($this->object->getOrderingType() == OQ_NESTED_TERMS
852  ||$this->object->getOrderingType() == OQ_NESTED_PICTURES)
853  {
854  $this->object->setOutputType(OUTPUT_JAVASCRIPT);
855 
856  // generate the question output
857  include_once "./Services/UICore/classes/class.ilTemplate.php";
858  $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
859 
860  $jsswitch = "";
861 
862  include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
863  include_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
864  $answers = new ilNestedOrderingGUI($this->lng->txt("answers"), "answers");
865  $answers->setOrderingType($this->object->getOrderingType());
866  $answers->setObjAnswersArray($this->object->answers);
867 
868  if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
869  {
870  $answers->setImagePath($this->object->getImagePath());
871  $answers->setImagePathWeb($this->object->getImagePathWeb());
872  $answers->setThumbPrefix($this->object->getThumbPrefix());
873  }
874 
875  $template->setCurrentBlock('nested_ordering_output');
876  $template->setVariable('NESTED_ORDERING',$answers->getHtml());
877  $template->parseCurrentBlock();
878  $questiontext = $this->object->getQuestion();
879  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
880  $questionoutput = $jsswitch . $template->get();
881  if (!$show_question_only)
882  {
883  // get page object output
884  $questionoutput = $this->getILIASPage($questionoutput);
885  }
886  return $questionoutput;
887 
888  }
889  else
890  {
891  $jsswitch = "";
892  if (strcmp($this->ctrl->getCmd(), 'preview') == 0)
893  {
894  if (array_key_exists('js', $_GET))
895  {
896  $ilUser->writePref('tst_javascript', $_GET['js']);
897  }
898  $jstemplate = new ilTemplate("tpl.il_as_qpl_javascript_switch.html", TRUE, TRUE, "Modules/TestQuestionPool");
899  if ($ilUser->getPref("tst_javascript") == 1)
900  {
901  $jstemplate->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript_disable.png"));
902  $jstemplate->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("disable_javascript"));
903  $jstemplate->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("disable_javascript"));
904  $this->ctrl->setParameterByClass($this->ctrl->getCmdClass(), "js", "0");
905  $jstemplate->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTargetByClass($this->ctrl->getCmdClass(), $this->ctrl->getCmd()));
906  }
907  else
908  {
909  $jstemplate->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript.png"));
910  $jstemplate->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("enable_javascript"));
911  $jstemplate->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("enable_javascript"));
912  $this->ctrl->setParameterByClass($this->ctrl->getCmdClass(), "js", "1");
913  $jstemplate->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTargetByClass($this->ctrl->getCmdClass(), $this->ctrl->getCmd()));
914  }
915  $jsswitch = $jstemplate->get();
916  if ($ilUser->getPref('tst_javascript')) $this->object->setOutputType(OUTPUT_JAVASCRIPT);
917  }
918 
919  if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT)
920  {
921  // BEGIN: add javascript code for javascript enabled ordering questions
922  $this->tpl->addBlockFile("CONTENT_BLOCK", "head_content", "tpl.il_as_qpl_ordering_output_javascript.html", "Modules/TestQuestionPool");
923  $this->tpl->touchBlock('head_content');
924 
925  require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
928  // END: add javascript code for javascript enabled ordering questions
929 
930  // BEGIN: add additional stylesheet for javascript enabled ordering questions
931  $this->tpl->setCurrentBlock("AdditionalStyle");
932  $this->tpl->setVariable("LOCATION_ADDITIONAL_STYLESHEET", ilUtil::getStyleSheetLocation("output", "test_javascript.css", "Modules/TestQuestionPool"));
933  $this->tpl->parseCurrentBlock();
934  // END: add additional stylesheet for javascript enabled ordering questions
935  }
936 
937  if ($this->object->getOutputType() != OUTPUT_JAVASCRIPT)
938  {
939  foreach ($keys as $idx)
940  {
941  $answer = $this->object->answers[$idx];
942  if ($this->object->getOrderingType() == OQ_PICTURES)
943  {
944  $template->setCurrentBlock("ordering_row_standard_pictures");
945  $template->setVariable("PICTURE_HREF", $this->object->getImagePathWeb() . $answer->getAnswertext());
946  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
947  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
948  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
949  $template->setVariable("THUMB_HREF", $thumbweb);
950  $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
951  $template->setVariable("THUMB_TITLE", $this->lng->txt("enlarge"));
952  $template->setVariable("ANSWER_ID", $answer->getRandomID());
953  $template->parseCurrentBlock();
954  }
955  else
956  {
957  $template->setCurrentBlock("ordering_row_standard_text");
958  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
959  $template->setVariable("ANSWER_ID", $answer->getRandomID());
960  $template->parseCurrentBlock();
961  }
962  $template->setCurrentBlock("ordering_row_standard");
963  $template->setVariable("ANSWER_ID", $answer->getRandomID());
964  $template->parseCurrentBlock();
965  }
966  }
967  else
968  {
969  foreach ($keys as $idx)
970  {
971  $answer = $this->object->answers[$idx];
972  if ($this->object->getOrderingType() == OQ_PICTURES)
973  {
974  $template->setCurrentBlock("ordering_row_javascript_pictures");
975  $template->setVariable("PICTURE_HREF", $this->object->getImagePathWeb() . $answer->getAnswertext());
976  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
977  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
978  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
979  $template->setVariable("THUMB_HREF", $thumbweb);
980  $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
981  $template->setVariable("THUMB_TITLE", $this->lng->txt("thumbnail"));
982  $template->setVariable("ENLARGE_HREF", ilUtil::getImagePath("enlarge.png", FALSE));
983  $template->setVariable("ENLARGE_ALT", $this->lng->txt("enlarge"));
984  $template->setVariable("ENLARGE_TITLE", $this->lng->txt("enlarge"));
985  $template->setVariable("ANSWER_ID", $answer->getRandomID());
986  $template->parseCurrentBlock();
987  }
988  else
989  {
990  $template->setCurrentBlock("ordering_row_javascript_text");
991  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
992  $template->setVariable("ANSWER_ID", $answer->getRandomID());
993  $template->parseCurrentBlock();
994  }
995  }
996  $template->setCurrentBlock("ordering_with_javascript");
997  if ($this->object->getOrderingType() == OQ_PICTURES)
998  {
999  $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_pictures"));
1000  }
1001  else
1002  {
1003  $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_definitions"));
1004  }
1005  $template->parseCurrentBlock();
1006  }
1007  $questiontext = $this->object->getQuestion();
1008  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1009  $questionoutput = $jsswitch . $template->get();
1010  if (!$show_question_only)
1011  {
1012  // get page object output
1013  $questionoutput = $this->getILIASPage($questionoutput);
1014  }
1015  return $questionoutput;
1016  }
1017  }
1018 
1019  private function getRandomIdToAnswerMap()
1020  {
1021  $randomIdToAnswerMap = array();
1022 
1023  foreach($this->object->answers as $answer)
1024  {
1025  $randomIdToAnswerMap[$answer->getRandomId()] = $answer;
1026  }
1027 
1028  return $randomIdToAnswerMap;
1029  }
1030 
1031  function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $user_post_solution = FALSE)
1032  {
1033  // shuffle output
1034  $keys = array();
1035  if (is_array($user_post_solution))
1036  {
1037  $keys = $_SESSION["ordering_keys"];
1038  }
1039  else
1040  {
1041  $keys = array_keys($this->object->answers);
1042  shuffle($keys);
1043  }
1044  $_SESSION["ordering_keys"] = $keys;
1045 
1046  // generate the question output
1047  include_once "./Services/UICore/classes/class.ilTemplate.php";
1048 
1049  $template = new ilTemplate("tpl.il_as_qpl_ordering_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
1050  if ($this->object->getOrderingType() == OQ_NESTED_TERMS
1051  || $this->object->getOrderingType() == OQ_NESTED_PICTURES)
1052  {
1053  $this->object->setOutputType(OUTPUT_JAVASCRIPT);
1054  include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
1055  include_once 'Modules/TestQuestionPool/classes/class.ilNestedOrderingGUI.php';
1056  $answerGUI = new ilNestedOrderingGUI($this->lng->txt("answers"), "answers");
1057  $answerGUI->setInstanceId('participant');
1058  $answerGUI->setOrderingType($this->object->getOrderingType());
1059 
1060  $answerMap = $this->getRandomIdToAnswerMap();
1061 
1062  $answerArray = array();
1063  $shuffleAnswers = false;
1064 
1065  if( is_array($user_post_solution) && isset($user_post_solution['answers_ordering__participant']) )
1066  {
1067  $answers_ordering = $_POST['answers_ordering__participant'];
1068  $user_solution_hierarchy = json_decode($answers_ordering);
1069  $with_random_id = true;
1070  $this->object->setLeveledOrdering($user_solution_hierarchy, $with_random_id);
1071 
1072  foreach($this->object->leveled_ordering as $randomId => $depth)
1073  {
1074  $answ = new ASS_AnswerOrdering(
1075  $answerMap[$randomId]->getAnswertext(), $randomId, $depth
1076  );
1077 
1078  $answerArray[] = $answ;
1079  }
1080  }
1081  else
1082  {
1083  include_once "./Modules/Test/classes/class.ilObjTest.php";
1084 
1085  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1086  {
1087  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1088  }
1089 
1090  $solutions =& $this->object->getSolutionValues($active_id, $pass);
1091 
1092  if( count($solutions) )
1093  {
1094  foreach($solutions as $solution)
1095  {
1096  list($randomId, $depth) = explode(':', $solution['value2']);
1097 
1098  $answ = new ASS_AnswerOrdering(
1099  $answerMap[$randomId]->getAnswertext(), $randomId, $depth
1100  );
1101 
1102  $answerArray[] = $answ;
1103  }
1104  }
1105  else
1106  {
1107  $answerArray = $this->object->answers;
1108  $shuffleAnswers = true;
1109  }
1110  }
1111 
1112  $answerGUI->setObjAnswersArray($answerArray, $shuffleAnswers);
1113 
1114  if($this->object->getOrderingType() == OQ_NESTED_PICTURES)
1115  {
1116  $answerGUI->setImagePath($this->object->getImagePath());
1117  $answerGUI->setImagePathWeb($this->object->getImagePathWeb());
1118  $answerGUI->setThumbPrefix($this->object->getThumbPrefix());
1119  }
1120 
1121  $template->setCurrentBlock('nested_ordering_output');
1122  $template->setVariable('NESTED_ORDERING',$answerGUI->getHtml($shuffleAnswers));
1123  $template->parseCurrentBlock();
1124 
1125  $questiontext = $this->object->getQuestion();
1126  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1127  $questionoutput = $template->get();
1128  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1129  return $pageoutput;
1130  }
1131  else
1132  {
1133  if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT)
1134  {
1135  // BEGIN: add javascript code for javascript enabled ordering questions
1136  $this->tpl->addBlockFile("CONTENT_BLOCK", "head_content", "tpl.il_as_qpl_ordering_output_javascript.html", "Modules/TestQuestionPool");
1137  $this->tpl->touchBlock("head_content");
1138 
1139  require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
1142  // END: add javascript code for javascript enabled ordering questions
1143 
1144  // BEGIN: add additional stylesheet for javascript enabled ordering questions
1145  $this->tpl->setCurrentBlock("AdditionalStyle");
1146  $this->tpl->setVariable("LOCATION_ADDITIONAL_STYLESHEET", ilUtil::getStyleSheetLocation("output", "test_javascript.css", "Modules/TestQuestionPool"));
1147  $this->tpl->parseCurrentBlock();
1148  // END: add additional stylesheet for javascript enabled ordering questions
1149 
1150  // BEGIN: onsubmit form action for javascript enabled ordering questions
1151  $this->tpl->setVariable("ON_SUBMIT", "return saveOrder('orderlist');");
1152  // END: onsubmit form action for javascript enabled ordering questions
1153  }
1154 
1155  // get the solution of the user for the active pass or from the last pass if allowed
1156  if ($active_id)
1157  {
1158  $solutions = NULL;
1159  include_once "./Modules/Test/classes/class.ilObjTest.php";
1160  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1161  {
1162  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1163  }
1164  if (is_array($user_post_solution))
1165  {
1166  $solutions = array();
1167  foreach ($user_post_solution as $key => $value)
1168  {
1169  if (preg_match("/order_(\d+)/", $key, $matches))
1170  {
1171  foreach ($this->object->getAnswers() as $answeridx => $answer)
1172  {
1173  if ($answer->getRandomID() == $matches[1])
1174  {
1175  array_push($solutions, array("value1" => $answeridx, "value2" => $value));
1176  }
1177  }
1178  }
1179  }
1180  }
1181  else
1182  {
1183  $solutions =& $this->object->getSolutionValues($active_id, $pass);
1184  }
1185 
1186  if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT)
1187  {
1188  $solution_script .= "";
1189  $jssolutions = array();
1190  foreach ($solutions as $idx => $solution_value)
1191  {
1192  if ((strcmp($solution_value["value2"], "") != 0) && (strcmp($solution_value["value1"], "") != 0))
1193  {
1194  $jssolutions[$solution_value["value2"]] = $solution_value["value1"];
1195  }
1196  }
1197  if (count($jssolutions))
1198  {
1199  ksort($jssolutions);
1200  $js = "";
1201  foreach ($jssolutions as $key => $value)
1202  {
1203  if (is_object($this->object->getAnswer($value)))
1204  {
1205  $js .= "initialorder.push('id_" . $this->object->getAnswer($value)->getRandomID() . "');";
1206  }
1207  }
1208  $js .= "restoreInitialOrder();";
1209  }
1210  if (strlen($js))
1211  {
1212  $template->setCurrentBlock("javascript_restore_order");
1213  $template->setVariable("RESTORE_ORDER", $js);
1214  $template->parseCurrentBlock();
1215  }
1216  }
1217  }
1218 
1219  if ($this->object->getOutputType() != OUTPUT_JAVASCRIPT)
1220  {
1221  foreach ($keys as $idx)
1222  {
1223  $answer = $this->object->answers[$idx];
1224  if ($this->object->getOrderingType() == OQ_PICTURES)
1225  {
1226  $template->setCurrentBlock("ordering_row_standard_pictures");
1227  $template->setVariable("PICTURE_HREF", $this->object->getImagePathWeb() . $answer->getAnswertext());
1228  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
1229  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
1230  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
1231  $template->setVariable("THUMB_HREF", $thumbweb);
1232  $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
1233  $template->setVariable("THUMB_TITLE", $this->lng->txt("enlarge"));
1234  $template->setVariable("ANSWER_ID", $answer->getRandomID());
1235  $template->parseCurrentBlock();
1236  }
1237  else
1238  {
1239  $template->setCurrentBlock("ordering_row_standard_text");
1240  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
1241  $template->setVariable("ANSWER_ID", $answer->getRandomID());
1242  $template->parseCurrentBlock();
1243  }
1244  $template->setCurrentBlock("ordering_row_standard");
1245  $template->setVariable("ANSWER_ID", $answer->getRandomID());
1246  if (is_array($solutions))
1247  {
1248  foreach ($solutions as $solution)
1249  {
1250  if (($solution["value1"] == $idx) && (strlen($solution["value2"])))
1251  {
1252  $template->setVariable("ANSWER_ORDER", " value=\"" . $solution["value2"] . "\"");
1253  }
1254  }
1255  }
1256  $template->parseCurrentBlock();
1257  }
1258  }
1259  else
1260  {
1261  foreach ($keys as $idx)
1262  {
1263  $answer = $this->object->answers[$idx];
1264  if ($this->object->getOrderingType() == OQ_PICTURES)
1265  {
1266  $template->setCurrentBlock("ordering_row_javascript_pictures");
1267  $template->setVariable("PICTURE_HREF", $this->object->getImagePathWeb() . $answer->getAnswertext());
1268  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getAnswertext();
1269  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $answer->getAnswertext();
1270  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
1271  $template->setVariable("THUMB_HREF", $thumbweb);
1272  $template->setVariable("THUMB_ALT", $this->lng->txt("thumbnail"));
1273  $template->setVariable("THUMB_TITLE", $this->lng->txt("thumbnail"));
1274  $template->setVariable("ENLARGE_HREF", ilUtil::getImagePath("enlarge.png", FALSE));
1275  $template->setVariable("ENLARGE_ALT", $this->lng->txt("enlarge"));
1276  $template->setVariable("ENLARGE_TITLE", $this->lng->txt("enlarge"));
1277  $template->setVariable("ANSWER_ID", $answer->getRandomID());
1278  $template->parseCurrentBlock();
1279  }
1280  else
1281  {
1282  $template->setCurrentBlock("ordering_row_javascript_text");
1283  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
1284  $template->setVariable("ANSWER_ID", $answer->getRandomID());
1285  $template->parseCurrentBlock();
1286  }
1287  }
1288  $template->setCurrentBlock("ordering_with_javascript");
1289  if ($this->object->getOrderingType() == OQ_PICTURES)
1290  {
1291  $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_pictures"));
1292  }
1293  else
1294  {
1295  $template->setVariable("RESET_POSITIONS", $this->lng->txt("reset_definitions"));
1296  }
1297  $template->parseCurrentBlock();
1298  }
1299  $questiontext = $this->object->getQuestion();
1300  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1301  $questionoutput = $template->get();
1302  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1303  return $pageoutput;
1304  }
1305  }
1306 
1314  function setQuestionTabs()
1315  {
1316  global $rbacsystem, $ilTabs;
1317 
1318  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1319  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1320  $q_type = $this->object->getQuestionType();
1321 
1322  if (strlen($q_type))
1323  {
1324  $classname = $q_type . "GUI";
1325  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1326  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1327  }
1328 
1329  if ($_GET["q_id"])
1330  {
1331  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1332  {
1333  // edit page
1334  $ilTabs->addTarget("edit_page",
1335  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1336  array("edit", "insert", "exec_pg"),
1337  "", "", $force_active);
1338  }
1339 
1340  // edit page
1341  $ilTabs->addTarget("preview",
1342  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "preview"),
1343  array("preview"),
1344  "ilAssQuestionPageGUI", "", $force_active);
1345  }
1346 
1347  $force_active = false;
1348  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1349  {
1350  $url = "";
1351  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1352  $commands = $_POST["cmd"];
1353  if (is_array($commands))
1354  {
1355  foreach ($commands as $key => $value)
1356  {
1357  if (preg_match("/^delete_.*/", $key, $matches))
1358  {
1359  $force_active = true;
1360  }
1361  }
1362  }
1363  // edit question properties
1364  $ilTabs->addTarget("edit_question",
1365  $url,
1366  array("orderNestedTerms","orderNestedPictures","editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "changeToPictures", "uploadanswers", "changeToText", "upanswers", "downanswers", "originalSyncForm"),
1367  $classname, "", $force_active);
1368  }
1369 
1370  // add tab for question feedback within common class assQuestionGUI
1371  $this->addTab_QuestionFeedback($ilTabs);
1372 
1373  // add tab for question hint within common class assQuestionGUI
1374  $this->addTab_QuestionHints($ilTabs);
1375 
1376  if ($_GET["q_id"])
1377  {
1378  $ilTabs->addTarget("solution_hint",
1379  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
1380  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
1381  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
1382  ),
1383  $classname,
1384  ""
1385  );
1386  }
1387 
1388  // Assessment of questions sub menu entry
1389  if ($_GET["q_id"])
1390  {
1391  $ilTabs->addTarget("statistics",
1392  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1393  array("assessment"),
1394  $classname, "");
1395  }
1396 
1397  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
1398  {
1399  $ref_id = $_GET["calling_test"];
1400  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
1401 
1402  global $___test_express_mode;
1403 
1404  if (!$_GET['test_express_mode'] && !$___test_express_mode) {
1405  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
1406  }
1407  else {
1409  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
1410  }
1411  }
1412  else
1413  {
1414  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
1415  }
1416  }
1417 
1418  function getSpecificFeedbackOutput($active_id, $pass)
1419  {
1420  $output = '<table class="ilTstSpecificFeedbackTable"><tbody>';
1421 
1422  foreach($this->object->getAnswers() as $idx => $answer)
1423  {
1424  $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
1425  $this->object->getId(), $idx
1426  );
1427 
1428  $output .= "<tr><td><b><i>{$answer->getAnswerText()}</i></b></td><td>{$feedback}</td></tr>";
1429  }
1430 
1431  $output .= '</tbody></table>';
1432 
1433  return $this->object->prepareTextareaOutput($output, TRUE);
1434  }
1435 
1436  private function getDepthRecursive($child, $ordering_depth)
1437  {
1438  if(is_array($child->children))
1439  {
1440  foreach($child->children as $grand_child)
1441  {
1442  $ordering_depth++;
1443  $this->leveled_ordering[] = $ordering_depth;
1444  $this->getDepthRecursive($grand_child, $ordering_depth);
1445  }
1446  }
1447  else
1448  {
1449  $ordering_depth++;
1450  $this->leveled_ordering[] = $ordering_depth;
1451  }
1452  }
1453 
1454  public function setLeveledOrdering($new_hierarchy)
1455  {
1456  foreach($new_hierarchy as $id)
1457  {
1458  $ordering_depth = 0;
1459  $this->leveled_ordering[] = $ordering_depth;
1460 
1461  if(is_array($id->children))
1462  {
1463  foreach($id->children as $child)
1464  {
1465  $this->getDepthRecursive($child, $ordering_depth);
1466  }
1467  }
1468  }
1469  }
1470 
1471  private function getOldLeveledOrdering()
1472  {
1473  global $ilDB;
1474 
1475  $res = $ilDB->queryF('SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY solution_order ASC',
1476  array('integer'), array($this->object->getId()));
1477  while($row = $ilDB->fetchAssoc($res))
1478  {
1479  $this->old_ordering_depth[] = $row['depth'];
1480  }
1482  }
1483 
1494  {
1495  return array();
1496  }
1497 
1508  {
1509  return array('element_height', 'thumb_geometry','answers');
1510  }
1511 
1513  {
1514  $element = $form->getItemByPostvar('element_height');
1515  if($element)
1516  {
1517  $_POST['element_height'] = $this->object->getElementHeight();
1518  $element->setValue( $this->object->getElementHeight() );
1519  }
1520  $element = $form->getItemByPostvar('thumb_geometry');
1521 
1522  if($element)
1523  {
1524  $_POST['thump_geometry'] = $this->object->getThumbGeometry();
1525  $element->setValue( $this->object->getThumbGeometry() );
1526  $element->setRequired( false );
1527  }
1528 
1529  $element = $form->getItemByPostvar('answers');
1530  $element->setRequired(false);
1531  }
1532 
1541  public function getAggregatedAnswersView($relevant_answers)
1542  {
1543  $passes = array();
1544  foreach($relevant_answers as $pass)
1545  {
1546  $passes[$pass['active_fi'].'-'.$pass['pass']] = '-';
1547  }
1548  $passcount = count($passes);
1549  foreach($relevant_answers as $pass)
1550  {
1551  $actives[$pass['active_fi']] = $pass['active_fi'];
1552  }
1553  $usercount = count($actives);
1554  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_header.html', true, true, "Modules/TestQuestionPool");
1555  $tpl->setVariable('HEADERTEXT', $this->lng->txt('overview'));
1556  $tpl->setVariable('NUMBER_OF_USERS_INFO', $this->lng->txt('number_of_users'));
1557  $tpl->setVariable('NUMBER_OF_USERS', $usercount);
1558  $tpl->setVariable('NUMBER_OF_PASSES_INFO', $this->lng->txt('number_of_passes'));
1559  $tpl->setVariable('NUMBER_OF_PASSES', $passcount);
1560 
1561  return $tpl->get() . $this->renderAggregateView(
1562  $this->aggregateAnswers( $relevant_answers, $this->object->getAnswers() ) )->get();
1563  }
1564 
1565  public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
1566  {
1567  $passdata = array(); // Regroup answers into one line per pass.
1568  foreach($relevant_answers_chosen as $answer_chosen)
1569  {
1570  $pass_ident = $answer_chosen['active_fi'].'-'. $answer_chosen['pass'];
1571  $answers = $passdata[$pass_ident];
1572  if(!strlen($answers))
1573  {
1574  $answers = array();
1575  }
1576  else
1577  {
1578  $answers = explode(',',$answers);
1579  }
1580  if($this->object->getOrderingType() == OQ_TERMS || $this->object->getOrderingType() == OQ_PICTURES)
1581  {
1582  $answers[$answer_chosen['value2']] = $answer_chosen['value1'];
1583  } else {
1584  $parts = explode(':',$answer_chosen['value2']);
1585  $item = $parts[0];
1586  $depth = $parts[1];
1587  $answers[$answer_chosen['value1']] = implode('|', array($depth,$item));
1588  }
1589  $passdata[$pass_ident] = implode(',', $answers);
1590  }
1591 
1592  $variants = array();
1593  foreach($passdata as $line_data)
1594  {
1595  if(isset($variants[$line_data]))
1596  {
1597  $variants[$line_data]++;
1598  }
1599  else
1600  {
1601  $variants[$line_data] = 1;
1602  }
1603  }
1604 
1605  return $variants;
1606 
1607  }
1608 
1614  public function renderAggregateView($aggregate)
1615  {
1616  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
1617  $tpl->setVariable( 'OPTION_HEADER', $this->lng->txt('answer_variant') );
1618  $tpl->setVariable( 'COUNT_HEADER', $this->lng->txt('count') );
1619  $tpl->setVariable( 'AGGREGATION_HEADER', $this->lng->txt('aggregated_answers_header') );
1620  foreach ($aggregate as $answers => $line_data)
1621  {
1622  $tpl->setCurrentBlock( 'aggregaterow' );
1623  $html = '<ul style="list-style: none;">';
1624 
1625  $answer_entries = explode(',',$answers);
1626  foreach($answer_entries as $key => $line)
1627  {
1628  $html .= '<li>';
1629  if($this->object->getOrderingType() == OQ_NESTED_TERMS || $this->object->getOrderingType() === OQ_NESTED_PICTURES)
1630  {
1631  $answer_parts = explode( '|', $line );
1632  $line_item = $answer_parts[1];
1633  if(isset($answer_parts[0]))
1634  {
1635  $indent_level = $answer_parts[0];
1636  }
1637  else
1638  {
1639  $indent_level = 0;
1640  }
1641  for($i = 0; $i < $indent_level; $i++)
1642  {
1643  $html .= '&nbsp;<small>&gt;</small>&nbsp;';
1644  }
1645  $answer_objs = $this->object->getAnswers();
1646  foreach($answer_objs as $candidate)
1647  {
1648  if($candidate->getRandomId() == $line_item)
1649  {
1650  $answer_obj = $candidate;
1651  }
1652  }
1653 
1654  } else {
1655  $line_item = $line;
1656  $answer_obj = $this->object->getAnswer($line_item);
1657 
1658  }
1659 
1660  if($this->object->getOrderingType() == OQ_TERMS || $this->object->getOrderingType() == OQ_NESTED_TERMS)
1661  {
1662  $html .= $answer_obj->getAnswertext();
1663  } else {
1664  $html .= '&nbsp;<img src="'
1665  . $this->object->getImagePathWeb()
1666  . $this->object->getThumbPrefix()
1667  . $answer_obj->getAnswertext()
1668  . '" />'; // No, seriously.
1669  }
1670  $html .= '</li>';
1671  }
1672  $html .= '</ul>';
1673  $tpl->setVariable( 'COUNT', $line_data );
1674  $tpl->setVariable( 'OPTION', $html );
1675 
1676  $tpl->parseCurrentBlock();
1677  }
1678  return $tpl;
1679  }
1680 }