ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assMatchingQuestionGUI.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 
24 {
34  public function __construct($id = -1)
35  {
37  include_once "./Modules/TestQuestionPool/classes/class.assMatchingQuestion.php";
38  $this->object = new assMatchingQuestion();
39  $this->setErrorMessage($this->lng->txt("msg_form_save_error"));
40  if ($id >= 0)
41  {
42  $this->object->loadFromDb($id);
43  }
44  }
45 
53  public function writePostData($always = false)
54  {
55  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
56  if (!$hasErrors)
57  {
61  $this->saveTaxonomyAssignments();
62  return 0;
63  }
64  return 1;
65  }
66 
67  public function writeAnswerSpecificPostData($always = true)
68  {
69  // Delete all existing answers and create new answers from the form data
70  $this->object->flushMatchingPairs();
71  $this->object->flushTerms();
72  $this->object->flushDefinitions();
73 
74  // add terms
75  require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php';
76  foreach ($_POST['terms']['answer'] as $index => $answer)
77  {
78  $filename = $_POST['terms']['imagename'][$index];
79  if (strlen( $_FILES['terms']['name']['image'][$index] ))
80  {
81  // upload the new file
82  $name = $_FILES['terms']['name']['image'][$index];
83  if ($this->object->setImageFile( $_FILES['terms']['tmp_name']['image'][$index],
84  $this->object->getEncryptedFilename( $name )
85  )
86  )
87  {
88  $filename = $this->object->getEncryptedFilename( $name );
89  }
90  else
91  {
92  $filename = "";
93  }
94  }
95  $this->object->addTerm( new assAnswerMatchingTerm($answer, $filename, $_POST['terms']['identifier'][$index])
96  );
97  }
98  // add definitions
99  require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php';
100  foreach ($_POST['definitions']['answer'] as $index => $answer)
101  {
102  $filename = $_POST['definitions']['imagename'][$index];
103  if (strlen( $_FILES['definitions']['name']['image'][$index] ))
104  {
105  // upload the new file
106  $name = $_FILES['definitions']['name']['image'][$index];
107  if ($this->object->setImageFile( $_FILES['definitions']['tmp_name']['image'][$index],
108  $this->object->getEncryptedFilename( $name )
109  )
110  )
111  {
112  $filename = $this->object->getEncryptedFilename( $name );
113  }
114  else
115  {
116  $filename = "";
117  }
118  }
119  $this->object->addDefinition(
120  new assAnswerMatchingDefinition($answer, $filename, $_POST['definitions']['identifier'][$index])
121  );
122  }
123 
124  // add matching pairs
125  if (is_array( $_POST['pairs']['points'] ))
126  {
127  require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php';
128  foreach ($_POST['pairs']['points'] as $index => $points)
129  {
130  $term_id = $_POST['pairs']['term'][$index];
131  $definition_id = $_POST['pairs']['definition'][$index];
132  $this->object->addMatchingPair( $this->object->getTermWithIdentifier( $term_id ),
133  $this->object->getDefinitionWithIdentifier( $definition_id ),
134  $points
135  );
136  }
137  }
138  }
139 
140  public function writeQuestionSpecificPostData($always = true)
141  {
142  if (!$this->object->getSelfAssessmentEditingMode())
143  {
144  $this->object->setShuffle( $_POST["shuffle"] );
145  }
146  else
147  {
148  $this->object->setShuffle( 1 );
149  }
150  $this->object->setThumbGeometry( $_POST["thumb_geometry"] );
151  $this->object->setElementHeight( $_POST["element_height"] );
152  }
153 
154  public function uploadterms()
155  {
156  $this->writePostData(true);
157  $this->editQuestion();
158  }
159 
160  public function removeimageterms()
161  {
162  $this->writePostData(true);
163  $position = key($_POST['cmd']['removeimageterms']);
164  $this->object->removeTermImage($position);
165  $this->editQuestion();
166  }
167 
168  public function uploaddefinitions()
169  {
170  $this->writePostData(true);
171  $this->editQuestion();
172  }
173 
174  public function removeimagedefinitions()
175  {
176  $this->writePostData(true);
177  $position = key($_POST['cmd']['removeimagedefinitions']);
178  $this->object->removeDefinitionImage($position);
179  $this->editQuestion();
180  }
181 
182  public function addterms()
183  {
184  $this->writePostData();
185  $position = key($_POST["cmd"]["addterms"]);
186  $this->object->insertTerm($position+1);
187  $this->editQuestion();
188  }
189 
190  public function removeterms()
191  {
192  $this->writePostData();
193  $position = key($_POST["cmd"]["removeterms"]);
194  $this->object->deleteTerm($position);
195  $this->editQuestion();
196  }
197 
198  public function adddefinitions()
199  {
200  $this->writePostData();
201  $position = key($_POST["cmd"]["adddefinitions"]);
202  $this->object->insertDefinition($position+1);
203  $this->editQuestion();
204  }
205 
206  public function removedefinitions()
207  {
208  $this->writePostData();
209  $position = key($_POST["cmd"]["removedefinitions"]);
210  $this->object->deleteDefinition($position);
211  $this->editQuestion();
212  }
213 
214  public function addpairs()
215  {
216  $this->writePostData();
217  $position = key($_POST["cmd"]["addpairs"]);
218  $this->object->insertMatchingPair($position+1);
219  $this->editQuestion();
220  }
221 
222  public function removepairs()
223  {
224  $this->writePostData();
225  $position = key($_POST["cmd"]["removepairs"]);
226  $this->object->deleteMatchingPair($position);
227  $this->editQuestion();
228  }
229 
230  public function editQuestion($checkonly = FALSE)
231  {
232  $save = $this->isSaveCommand();
233  $this->getQuestionTemplate();
234 
235  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
236  $form = new ilPropertyFormGUI();
237  $form->setFormAction($this->ctrl->getFormAction($this));
238  $form->setTitle($this->outQuestionType());
239  $form->setMultipart(true);
240  $form->setTableWidth("100%");
241  $form->setId("matching");
242 
243 
244  // title, author, description, question, working time (assessment mode)
245  $this->addBasicQuestionFormProperties($form);
246  $this->populateQuestionSpecificFormPart( $form );
247  $this->populateAnswerSpecificFormPart( $form );
248  $this->populateTaxonomyFormSection($form);
249  $this->addQuestionFormCommandButtons($form);
250 
251  $errors = false;
252  if ($save)
253  {
254  $form->setValuesByPost();
255  $errors = !$form->checkInput();
256  $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
257  if( !$errors && !$this->isValidTermAndDefinitionAmount($form) && !$this->object->getSelfAssessmentEditingMode() )
258  {
259  $errors = true;
260  $terms = $form->getItemByPostVar('terms');
261  $terms->setAlert($this->lng->txt("msg_number_of_terms_too_low"));
262  ilUtil::sendFailure($this->lng->txt('form_input_not_valid'));
263  }
264  if ($errors) $checkonly = false;
265  }
266 
267  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
268  return $errors;
269  }
270 
276  {
277  $numTerms = count($form->getItemByPostVar('terms')->getValues());
278  $numDefinitions = count($form->getItemByPostVar('definitions')->getValues());
279 
280  if($numTerms >= $numDefinitions)
281  {
282  return true;
283  }
284 
285  return false;
286  }
287 
289  {
290  // Definitions
291  include_once "./Modules/TestQuestionPool/classes/class.ilMatchingWizardInputGUI.php";
292  $definitions = new ilMatchingWizardInputGUI($this->lng->txt( "definitions" ), "definitions");
293  if ($this->object->getSelfAssessmentEditingMode())
294  {
295  $definitions->setHideImages( true );
296  }
297 
298  $definitions->setRequired( true );
299  $definitions->setQuestionObject( $this->object );
300  $definitions->setTextName( $this->lng->txt( 'definition_text' ) );
301  $definitions->setImageName( $this->lng->txt( 'definition_image' ) );
302  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
303  if (!count( $this->object->getDefinitions() ))
304  {
305  $this->object->addDefinition( new assAnswerMatchingDefinition() );
306  }
307  $definitionvalues = $this->object->getDefinitions();
308  $definitions->setValues( $definitionvalues );
309  $definitions->checkInput();
310  $form->addItem( $definitions );
311 
312  // Terms
313  include_once "./Modules/TestQuestionPool/classes/class.ilMatchingWizardInputGUI.php";
314  $terms = new ilMatchingWizardInputGUI($this->lng->txt( "terms" ), "terms");
315  if ($this->object->getSelfAssessmentEditingMode())
316  $terms->setHideImages( true );
317  $terms->setRequired( true );
318  $terms->setQuestionObject( $this->object );
319  $terms->setTextName( $this->lng->txt( 'term_text' ) );
320  $terms->setImageName( $this->lng->txt( 'term_image' ) );
321  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
322  if (!count( $this->object->getTerms() ))
323  $this->object->addTerm( new assAnswerMatchingTerm() );
324  $termvalues = $this->object->getTerms();
325  $terms->setValues( $termvalues );
326  $terms->checkInput();
327  $form->addItem( $terms );
328 
329  // Matching Pairs
330  include_once "./Modules/TestQuestionPool/classes/class.ilMatchingPairWizardInputGUI.php";
331  $pairs = new ilMatchingPairWizardInputGUI($this->lng->txt( 'matching_pairs' ), 'pairs');
332  $pairs->setRequired( true );
333  $pairs->setTerms( $this->object->getTerms() );
334  $pairs->setDefinitions( $this->object->getDefinitions() );
335  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php";
336  if (count( $this->object->getMatchingPairs() ) == 0)
337  {
338  $this->object->addMatchingPair( new assAnswerMatchingPair($termvalues[0], $definitionvalues[0], 0) );
339  }
340  $pairs->setPairs( $this->object->getMatchingPairs() );
341  $form->addItem( $pairs );
342  return $form;
343  }
344 
346  {
347  // Edit mode
348  $hidden = new ilHiddenInputGUI("matching_type");
349  $hidden->setValue($matchingtype);
350  $form->addItem($hidden);
351 
352  if (!$this->object->getSelfAssessmentEditingMode())
353  {
354  // shuffle
355  $shuffle = new ilSelectInputGUI($this->lng->txt( "shuffle_answers" ), "shuffle");
356  $shuffle_options = array(
357  0 => $this->lng->txt( "no" ),
358  1 => $this->lng->txt( "matching_shuffle_terms_definitions" ),
359  2 => $this->lng->txt( "matching_shuffle_terms" ),
360  3 => $this->lng->txt( "matching_shuffle_definitions" )
361  );
362  $shuffle->setOptions( $shuffle_options );
363  $shuffle->setValue($this->object->getShuffle() != null ? $this->object->getShuffle() : 1);
364  $shuffle->setRequired( FALSE );
365  $form->addItem( $shuffle );
366 
367  $element_height = new ilNumberInputGUI($this->lng->txt( "element_height" ), "element_height");
368  $element_height->setValue( $this->object->getElementHeight() );
369  $element_height->setRequired( false );
370  $element_height->setMaxLength( 6 );
371  $element_height->setMinValue( 20 );
372  $element_height->setSize( 6 );
373  $element_height->setInfo( $this->lng->txt( "element_height_info" ) );
374  $form->addItem( $element_height );
375 
376  $geometry = new ilNumberInputGUI($this->lng->txt( "thumb_geometry" ), "thumb_geometry");
377  $geometry->setValue( $this->object->getThumbGeometry() );
378  $geometry->setRequired( true );
379  $geometry->setMaxLength( 6 );
380  $geometry->setMinValue( 20 );
381  $geometry->setSize( 6 );
382  $geometry->setInfo( $this->lng->txt( "thumb_geometry_info" ) );
383  $form->addItem( $geometry );
384  }
385  }
386 
387  function outQuestionForTest($formaction, $active_id, $pass = NULL, $is_postponed = FALSE, $user_post_solution = FALSE)
388  {
389  $test_output = $this->getTestOutput($active_id, $pass, $is_postponed, $user_post_solution);
390  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
391  $this->tpl->setVariable("FORMACTION", $formaction);
392  }
393 
408  $active_id,
409  $pass = NULL,
410  $graphicalOutput = FALSE,
411  $result_output = FALSE,
412  $show_question_only = TRUE,
413  $show_feedback = FALSE,
414  $show_correct_solution = FALSE,
415  $show_manual_scoring = FALSE,
416  $show_question_text = TRUE
417  )
418  {
419  // generate the question output
420  include_once "./Services/UICore/classes/class.ilTemplate.php";
421  $template = new ilTemplate("tpl.il_as_qpl_matching_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
422  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
423 
424  $solutions = array();
425  if (($active_id > 0) && (!$show_correct_solution))
426  {
427  include_once "./Modules/Test/classes/class.ilObjTest.php";
428  $solutions =& $this->object->getSolutionValues($active_id, $pass);
429  $solution_script .= "";
430  }
431  else
432  {
433  foreach ($this->object->getMatchingPairs() as $pair)
434  {
435  if( $pair->points <= 0 )
436  {
437  continue;
438  }
439 
440  $solutions[] = array(
441  "value1" => $pair->term->identifier,
442  "value2" => $pair->definition->identifier,
443  'points' => $pair->points
444  );
445  }
446  }
447 
448  $i = 0;
449 
450  foreach ($solutions as $solution)
451  {
452  $definition = $this->object->getDefinitionWithIdentifier($solution['value2']);
453  $term = $this->object->getTermWithIdentifier($solution['value1']);
454  $points = $solution['points'];
455 
456  if (is_object($definition))
457  {
458  if (strlen($definition->picture))
459  {
460  $template->setCurrentBlock('definition_image');
461  $template->setVariable('ANSWER_IMAGE_URL', $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $definition->picture);
462  $template->setVariable('ANSWER_IMAGE_ALT', (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : ilUtil::prepareFormOutput($definition->picture));
463  $template->setVariable('ANSWER_IMAGE_TITLE', (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : ilUtil::prepareFormOutput($definition->picture));
464  $template->setVariable('URL_PREVIEW', $this->object->getImagePathWeb() . $definition->picture);
465  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
466  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
467  $template->setVariable("TEXT_DEFINITION", (strlen($definition->text)) ? $this->lng->txt('definition') . ' ' . ($i+1) . ': ' . ilUtil::prepareFormOutput($definition->text) : $this->lng->txt('definition') . ' ' . ($i+1));
468  $template->parseCurrentBlock();
469  }
470  else
471  {
472  $template->setCurrentBlock('definition_text');
473  $template->setVariable("DEFINITION", $this->object->prepareTextareaOutput($definition->text, TRUE));
474  $template->parseCurrentBlock();
475  }
476  }
477  if (is_object($term))
478  {
479  if (strlen($term->picture))
480  {
481  $template->setCurrentBlock('term_image');
482  $template->setVariable('ANSWER_IMAGE_URL', $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $term->picture);
483  $template->setVariable('ANSWER_IMAGE_ALT', (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : ilUtil::prepareFormOutput($term->picture));
484  $template->setVariable('ANSWER_IMAGE_TITLE', (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : ilUtil::prepareFormOutput($term->picture));
485  $template->setVariable('URL_PREVIEW', $this->object->getImagePathWeb() . $term->picture);
486  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
487  $template->setVariable("TEXT_TERM", (strlen($term->text)) ? $this->lng->txt('term') . ' ' . ($i+1) . ': ' . ilUtil::prepareFormOutput($term->text) : $this->lng->txt('term') . ' ' . ($i+1));
488  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
489  $template->parseCurrentBlock();
490  }
491  else
492  {
493  $template->setCurrentBlock('term_text');
494  $template->setVariable("TERM", $this->object->prepareTextareaOutput($term->text, TRUE));
495  $template->parseCurrentBlock();
496  }
497  $i++;
498  }
499  if (($active_id > 0) && (!$show_correct_solution))
500  {
501  if ($graphicalOutput)
502  {
503  // output of ok/not ok icons for user entered solutions
504  $ok = false;
505  foreach ($this->object->getMatchingPairs() as $pair)
506  {
507  if( $this->isCorrectMatching($pair, $definition, $term) )
508  {
509  $ok = true;
510  }
511  }
512 
513  if ($ok)
514  {
515  $template->setCurrentBlock("icon_ok");
516  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.png"));
517  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
518  $template->parseCurrentBlock();
519  }
520  else
521  {
522  $template->setCurrentBlock("icon_ok");
523  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.png"));
524  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
525  $template->parseCurrentBlock();
526  }
527  }
528  }
529 
530  if ($result_output)
531  {
532  $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
533  $template->setCurrentBlock("result_output");
534  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
535  $template->parseCurrentBlock();
536  }
537 
538  $template->setCurrentBlock("row");
539  if ($this->object->getEstimatedElementHeight() > 0)
540  {
541  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
542  }
543  $template->setVariable("TEXT_MATCHES", $this->lng->txt("matches"));
544  $template->parseCurrentBlock();
545  }
546 
547  $questiontext = $this->object->getQuestion();
548  if ($show_question_text==true)
549  {
550  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
551  }
552 
553  $questionoutput = $template->get();
554 
555  $feedback = '';
556  if($show_feedback)
557  {
558  $fb = $this->getGenericFeedbackOutput($active_id, $pass);
559  $feedback .= strlen($fb) ? $fb : '';
560 
561  $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
562  $feedback .= strlen($fb) ? $fb : '';
563  }
564  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
565 
566  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
567 
568  $solutionoutput = $solutiontemplate->get();
569  if (!$show_question_only)
570  {
571  // get page object output
572  $solutionoutput = '<div class="ilc_question_Standard">'.$solutionoutput."</div>";
573  }
574  return $solutionoutput;
575  }
576 
577  public function getPreviewJS($show_question_only = FALSE)
578  {
579  global $ilUser;
580 
581  // generate the question output
582  include_once "./Services/UICore/classes/class.ilTemplate.php";
583  $template = new ilTemplate("tpl.il_as_qpl_matching_output_js.html", TRUE, TRUE, "Modules/TestQuestionPool");
584 
585  $jsswitch = "";
586  if (strcmp($this->ctrl->getCmd(), 'preview') == 0)
587  {
588  if (array_key_exists('js', $_GET))
589  {
590  $ilUser->writePref('tst_javascript', $_GET['js']);
591  }
592  $jstemplate = new ilTemplate("tpl.il_as_qpl_javascript_switch.html", TRUE, TRUE, "Modules/TestQuestionPool");
593  if ($ilUser->getPref("tst_javascript") == 1)
594  {
595  $jstemplate->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript_disable.png"));
596  $jstemplate->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("disable_javascript"));
597  $jstemplate->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("disable_javascript"));
598  $this->ctrl->setParameterByClass($this->ctrl->getCmdClass(), "js", "0");
599  $jstemplate->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTargetByClass($this->ctrl->getCmdClass(), $this->ctrl->getCmd()));
600  }
601  else
602  {
603  $jstemplate->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript.png"));
604  $jstemplate->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("enable_javascript"));
605  $jstemplate->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("enable_javascript"));
606  $this->ctrl->setParameterByClass($this->ctrl->getCmdClass(), "js", "1");
607  $jstemplate->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTargetByClass($this->ctrl->getCmdClass(), $this->ctrl->getCmd()));
608  }
609  $jsswitch = $jstemplate->get();
610  if ($ilUser->getPref('tst_javascript')) $this->object->setOutputType(OUTPUT_JAVASCRIPT);
611  }
612 
613  // shuffle output
614  $terms = $this->object->getTerms();
615  $definitions = $this->object->getDefinitions();
616  switch ($this->object->getShuffle())
617  {
618  case 1:
619  $terms = $this->object->pcArrayShuffle($terms);
620  $definitions = $this->object->pcArrayShuffle($definitions);
621  break;
622  case 2:
623  $terms = $this->object->pcArrayShuffle($terms);
624  break;
625  case 3:
626  $definitions = $this->object->pcArrayShuffle($definitions);
627  break;
628  }
629 
630  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
632 
633  // create definitions
634  $counter = 0;
635  foreach ($definitions as $definition)
636  {
637  if (strlen($definition->picture))
638  {
639  $template->setCurrentBlock("definition_picture");
640  $template->setVariable("DEFINITION_ID", $definition->identifier);
641  $template->setVariable("IMAGE_HREF", $this->object->getImagePathWeb() . $definition->picture);
642  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $definition->picture;
643  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $definition->picture;
644  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
645  $template->setVariable("THUMBNAIL_HREF", $thumbweb);
646  $template->setVariable("THUMB_ALT", $this->lng->txt("image"));
647  $template->setVariable("THUMB_TITLE", $this->lng->txt("image"));
648  $template->setVariable("TEXT_DEFINITION", (strlen($definition->text)) ? $this->object->prepareTextareaOutput($definition->text, TRUE) : '');
649  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
650  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
651  $template->parseCurrentBlock();
652  }
653  else
654  {
655  $template->setCurrentBlock("definition_text");
656  $template->setVariable("DEFINITION", $this->object->prepareTextareaOutput($definition->text, TRUE));
657  $template->parseCurrentBlock();
658  }
659 
660  $template->setCurrentBlock("droparea");
661  $template->setVariable("ID_DROPAREA", $definition->identifier);
662  $template->setVariable("QUESTION_ID", $this->object->getId());
663  if ($this->object->getEstimatedElementHeight() > 0)
664  {
665  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
666  }
667  $template->parseCurrentBlock();
668 
669  $template->setCurrentBlock("init_dropareas");
670  $template->setVariable("COUNTER", $counter++);
671  $template->setVariable("ID_DROPAREA", $definition->identifier);
672  $template->parseCurrentBlock();
673  }
674 
675 
676  // create terms
677  $counter = 0;
678  foreach ($terms as $term)
679  {
680  if (strlen($term->picture))
681  {
682  $template->setCurrentBlock("term_picture");
683  $template->setVariable("TERM_ID", $term->identifier);
684  $template->setVariable("IMAGE_HREF", $this->object->getImagePathWeb() . $term->picture);
685  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $term->picture;
686  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $term->picture;
687  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
688  $template->setVariable("THUMBNAIL_HREF", $thumbweb);
689  $template->setVariable("THUMB_ALT", $this->lng->txt("image"));
690  $template->setVariable("THUMB_TITLE", $this->lng->txt("image"));
691  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
692  $template->setVariable("TEXT_TERM", (strlen($term->text)) ? $this->object->prepareTextareaOutput($term->text, TRUE) : '');
693  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
694  $template->parseCurrentBlock();
695  }
696  else
697  {
698  $template->setCurrentBlock("term_text");
699  $template->setVariable("TERM_TEXT", $this->object->prepareTextareaOutput($term->text, TRUE));
700  $template->parseCurrentBlock();
701  }
702  $template->setCurrentBlock("draggable");
703  $template->setVariable("ID_DRAGGABLE", $term->identifier);
704  if ($this->object->getEstimatedElementHeight() > 0)
705  {
706  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
707  }
708  $template->parseCurrentBlock();
709 
710  $template->setCurrentBlock("init_draggables");
711  $template->setVariable("COUNTER", $counter++);
712  $template->setVariable("ID_DRAGGABLE", $term->identifier);
713  $template->parseCurrentBlock();
714  }
715 
716  $template->setVariable("RESET_BUTTON", $this->lng->txt("reset_terms"));
717 
718  $this->tpl->setVariable("LOCATION_ADDITIONAL_STYLESHEET", ilUtil::getStyleSheetLocation("output", "test_javascript.css", "Modules/TestQuestionPool"));
719 
720  $questiontext = $this->object->getQuestion();
721  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
722  $questionoutput = $jsswitch . $template->get();
723  if (!$show_question_only)
724  {
725  // get page object output
726  $questionoutput = $this->getILIASPage($questionoutput);
727  }
728  return $questionoutput;
729  }
730 
731  public function getPreview($show_question_only = FALSE)
732  {
733  global $ilUser;
734 
735  // generate the question output
736  include_once "./Services/UICore/classes/class.ilTemplate.php";
737  $template = new ilTemplate("tpl.il_as_qpl_matching_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
738 
739  $jsswitch = "";
740  if (strcmp($this->ctrl->getCmd(), 'preview') == 0)
741  {
742  if (array_key_exists('js', $_GET))
743  {
744  $ilUser->writePref('tst_javascript', $_GET['js']);
745  }
746  $jstemplate = new ilTemplate("tpl.il_as_qpl_javascript_switch.html", TRUE, TRUE, "Modules/TestQuestionPool");
747  if ($ilUser->getPref("tst_javascript") == 1)
748  {
749  $jstemplate->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript_disable.png"));
750  $jstemplate->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("disable_javascript"));
751  $jstemplate->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("disable_javascript"));
752  $this->ctrl->setParameterByClass($this->ctrl->getCmdClass(), "js", "0");
753  $jstemplate->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTargetByClass($this->ctrl->getCmdClass(), $this->ctrl->getCmd()));
754  }
755  else
756  {
757  $jstemplate->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript.png"));
758  $jstemplate->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("enable_javascript"));
759  $jstemplate->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("enable_javascript"));
760  $this->ctrl->setParameterByClass($this->ctrl->getCmdClass(), "js", "1");
761  $jstemplate->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTargetByClass($this->ctrl->getCmdClass(), $this->ctrl->getCmd()));
762  }
763  $jsswitch = $jstemplate->get();
764  if ($ilUser->getPref('tst_javascript')) $this->object->setOutputType(OUTPUT_JAVASCRIPT);
765  }
766 
767  if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT)
768  {
769  return $this->getPreviewJS($show_question_only);
770  }
771 
772  // shuffle output
773  $terms = $this->object->getTerms();
774  $definitions = $this->object->getDefinitions();
775  switch ($this->object->getShuffle())
776  {
777  case 1:
778  $terms = $this->object->pcArrayShuffle($terms);
779  $definitions = $this->object->pcArrayShuffle($definitions);
780  break;
781  case 2:
782  $terms = $this->object->pcArrayShuffle($terms);
783  break;
784  case 3:
785  $definitions = $this->object->pcArrayShuffle($definitions);
786  break;
787  }
788 
789  foreach ($definitions as $key => $definition)
790  {
791  if (is_object($definition))
792  {
793  if (strlen($definition->picture))
794  {
795  $template->setCurrentBlock('definition_image');
796  $template->setVariable('ANSWER_IMAGE_URL', $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $definition->picture);
797  $template->setVariable('ANSWER_IMAGE_ALT', (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : ilUtil::prepareFormOutput($definition->picture));
798  $template->setVariable('ANSWER_IMAGE_TITLE', (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : ilUtil::prepareFormOutput($definition->picture));
799  $template->setVariable('URL_PREVIEW', $this->object->getImagePathWeb() . $definition->picture);
800  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
801  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
802  $template->setVariable("TEXT_DEFINITION", (strlen($definition->text)) ? $this->lng->txt('definition') . ' ' . ($key+1) . ': ' . $this->object->prepareTextareaOutput($definition->text, TRUE) : $this->lng->txt('definition') . ' ' . ($key+1));
803  $template->parseCurrentBlock();
804  }
805  else
806  {
807  $template->setCurrentBlock('definition_text');
808  $template->setVariable("DEFINITION", $this->object->prepareTextareaOutput($definition->text, TRUE));
809  $template->parseCurrentBlock();
810  }
811  }
812 
813  $template->setCurrentBlock('option');
814  $template->setVariable("VALUE_OPTION", 0);
815  $template->setVariable("TEXT_OPTION", ilUtil::prepareFormOutput($this->lng->txt('please_select')));
816  $template->parseCurrentBlock();
817  foreach ($terms as $key => $term)
818  {
819  $template->setCurrentBlock('option');
820  $template->setVariable("VALUE_OPTION", $term->identifier);
821  $template->setVariable("TEXT_OPTION", (strlen($term->text)) ? $this->lng->txt('term') . ' ' . ($key +1) . ': ' . ilUtil::prepareFormOutput($term->text) : $this->lng->txt('term') . ' ' . ($key+1));
822  $template->parseCurrentBlock();
823  }
824 
825  $template->setCurrentBlock('row');
826  $template->setVariable("TEXT_MATCHES", $this->lng->txt("matches"));
827  if ($this->object->getEstimatedElementHeight() > 0)
828  {
829  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
830  }
831  $template->setVariable("QUESTION_ID", $this->object->getId());
832  $template->setVariable("DEFINITION_ID", $definition->identifier);
833  $template->parseCurrentBlock();
834  }
835 
836  foreach ($terms as $key => $term)
837  {
838  if (strlen($term->picture))
839  {
840  $template->setCurrentBlock('term_image');
841  $template->setVariable('ANSWER_IMAGE_URL', $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $term->picture);
842  $template->setVariable('ANSWER_IMAGE_ALT', (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : ilUtil::prepareFormOutput($term->picture));
843  $template->setVariable('ANSWER_IMAGE_TITLE', (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : ilUtil::prepareFormOutput($term->picture));
844  $template->setVariable('URL_PREVIEW', $this->object->getImagePathWeb() . $term->picture);
845  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
846  $template->setVariable("TEXT_TERM", (strlen($term->text)) ? $this->lng->txt('term') . ' ' . ($key+1) . ': ' . $this->object->prepareTextareaOutput($term->text, TRUE) : $this->lng->txt('term') . ' ' . ($key+1));
847  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
848  $template->parseCurrentBlock();
849  }
850  else
851  {
852  $template->setCurrentBlock('term_text');
853  $template->setVariable("TERM", $this->object->prepareTextareaOutput($term->text, TRUE));
854  $template->parseCurrentBlock();
855  }
856  $template->touchBlock('terms');
857  }
858 
859  $questiontext = $this->object->getQuestion();
860  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
861  $template->setVariable("TEXT_TERMS", ilUtil::prepareFormOutput($this->lng->txt('available_terms')));
862  $template->setVariable('TEXT_SELECTION', ilUtil::prepareFormOutput($this->lng->txt('selection')));
863  $questionoutput = $jsswitch . $template->get();
864  if (!$show_question_only)
865  {
866  // get page object output
867  $questionoutput = $this->getILIASPage($questionoutput);
868  }
869  return $questionoutput;
870  }
871 
872  protected function sortDefinitionsBySolution($solution)
873  {
874  $neworder = array();
875  foreach ($solution as $solution_values)
876  {
877  $id = $solution_values['value2'];
878  array_push($neworder, $this->object->getDefinitionWithIdentifier($id));
879  }
880  return $neworder;
881  }
882 
883  function getTestOutputJS($active_id, $pass = NULL, $is_postponed = FALSE, $user_post_solution = FALSE)
884  {
885  // generate the question output
886  include_once "./Services/UICore/classes/class.ilTemplate.php";
887  $template = new ilTemplate("tpl.il_as_qpl_matching_output_js.html", TRUE, TRUE, "Modules/TestQuestionPool");
888 
889  if ($active_id)
890  {
891  $solutions = NULL;
892  include_once "./Modules/Test/classes/class.ilObjTest.php";
893  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
894  {
895  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
896  }
897  if (is_array($user_post_solution))
898  {
899  $solutions = array();
900  foreach ($user_post_solution['matching'][$this->object->getId()] as $definition => $term)
901  {
902  array_push($solutions, array("value1" => $term, "value2" => $definition));
903  }
904  }
905  else
906  {
907  $solutions =& $this->object->getSolutionValues($active_id, $pass);
908  }
909 
910  foreach ($solutions as $idx => $solution_value)
911  {
912  if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT)
913  {
914  if (($solution_value["value2"] > -1) && ($solution_value["value1"] > -1))
915  {
916  $template->setCurrentBlock("restoreposition");
917  $template->setVariable("TERM_ID", $solution_value["value1"]);
918  $template->setVariable("PICTURE_DEFINITION_ID", $solution_value["value2"]);
919  $template->parseCurrentBlock();
920  }
921  }
922  }
923  }
924 
925  // shuffle output
926  $terms = $this->object->getTerms();
927  $definitions = $this->object->getDefinitions();
928  switch ($this->object->getShuffle())
929  {
930  case 1:
931  $terms = $this->object->pcArrayShuffle($terms);
932  if (count($solutions))
933  {
934  $definitions = $this->sortDefinitionsBySolution($solutions);
935  }
936  else
937  {
938  $definitions = $this->object->pcArrayShuffle($definitions);
939  }
940  break;
941  case 2:
942  $terms = $this->object->pcArrayShuffle($terms);
943  break;
944  case 3:
945  if (count($solutions))
946  {
947  $definitions = $this->sortDefinitionsBySolution($solutions);
948  }
949  else
950  {
951  $definitions = $this->object->pcArrayShuffle($definitions);
952  }
953  break;
954  }
955 
956  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
958 
959  // create definitions
960  $counter = 0;
961  foreach ($definitions as $definition)
962  {
963  if (strlen($definition->picture))
964  {
965  $template->setCurrentBlock("definition_picture");
966  $template->setVariable("DEFINITION_ID", $definition->identifier);
967  $template->setVariable("IMAGE_HREF", $this->object->getImagePathWeb() . $definition->picture);
968  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $definition->picture;
969  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $definition->picture;
970  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
971  $template->setVariable("THUMBNAIL_HREF", $thumbweb);
972  $template->setVariable("THUMB_ALT", $this->lng->txt("image"));
973  $template->setVariable("THUMB_TITLE", $this->lng->txt("image"));
974  $template->setVariable("TEXT_DEFINITION", (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : '');
975  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
976  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
977  $template->parseCurrentBlock();
978  }
979  else
980  {
981  $template->setCurrentBlock("definition_text");
982  $template->setVariable("DEFINITION", $this->object->prepareTextareaOutput($definition->text, true));
983  $template->parseCurrentBlock();
984  }
985 
986  $template->setCurrentBlock("droparea");
987  $template->setVariable("ID_DROPAREA", $definition->identifier);
988  $template->setVariable("QUESTION_ID", $this->object->getId());
989  if ($this->object->getEstimatedElementHeight() > 0)
990  {
991  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
992  }
993  $template->parseCurrentBlock();
994 
995  $template->setCurrentBlock("init_dropareas");
996  $template->setVariable("COUNTER", $counter++);
997  $template->setVariable("ID_DROPAREA", $definition->identifier);
998  $template->parseCurrentBlock();
999  }
1000 
1001 
1002  // create terms
1003  $counter = 0;
1004  foreach ($terms as $term)
1005  {
1006  if (strlen($term->picture))
1007  {
1008  $template->setCurrentBlock("term_picture");
1009  $template->setVariable("TERM_ID", $term->identifier);
1010  $template->setVariable("IMAGE_HREF", $this->object->getImagePathWeb() . $term->picture);
1011  $thumbweb = $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $term->picture;
1012  $thumb = $this->object->getImagePath() . $this->object->getThumbPrefix() . $term->picture;
1013  if (!@file_exists($thumb)) $this->object->rebuildThumbnails();
1014  $template->setVariable("THUMBNAIL_HREF", $thumbweb);
1015  $template->setVariable("THUMB_ALT", $this->lng->txt("image"));
1016  $template->setVariable("THUMB_TITLE", $this->lng->txt("image"));
1017  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
1018  $template->setVariable("TEXT_TERM", (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : '');
1019  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
1020  $template->parseCurrentBlock();
1021  }
1022  else
1023  {
1024  $template->setCurrentBlock("term_text");
1025  $template->setVariable("TERM_TEXT", $this->object->prepareTextareaOutput($term->text, true));
1026  $template->parseCurrentBlock();
1027  }
1028  $template->setCurrentBlock("draggable");
1029  $template->setVariable("ID_DRAGGABLE", $term->identifier);
1030  if ($this->object->getEstimatedElementHeight() > 0)
1031  {
1032  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
1033  }
1034  $template->parseCurrentBlock();
1035 
1036  $template->setCurrentBlock("init_draggables");
1037  $template->setVariable("COUNTER", $counter++);
1038  $template->setVariable("ID_DRAGGABLE", $term->identifier);
1039  $template->parseCurrentBlock();
1040  }
1041 
1042  $template->setVariable("RESET_BUTTON", $this->lng->txt("reset_terms"));
1043 
1044  $this->tpl->setVariable("LOCATION_ADDITIONAL_STYLESHEET", ilUtil::getStyleSheetLocation("output", "test_javascript.css", "Modules/TestQuestionPool"));
1045 
1046  $questiontext = $this->object->getQuestion();
1047  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1048  $questionoutput = $template->get();
1049  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1050  return $pageoutput;
1051  }
1052 
1053  function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $user_post_solution = FALSE)
1054  {
1055  if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT)
1056  {
1057  return $this->getTestOutputJS($active_id, $pass, $is_postponed, $user_post_solution);
1058  }
1059  // generate the question output
1060  include_once "./Services/UICore/classes/class.ilTemplate.php";
1061  $template = new ilTemplate("tpl.il_as_qpl_matching_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
1062 
1063  if ($active_id)
1064  {
1065  $solutions = NULL;
1066  include_once "./Modules/Test/classes/class.ilObjTest.php";
1067  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1068  {
1069  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1070  }
1071  if (is_array($user_post_solution))
1072  {
1073  $solutions = array();
1074  foreach ($user_post_solution['matching'][$this->object->getId()] as $definition => $term)
1075  {
1076  array_push($solutions, array("value1" => $term, "value2" => $definition));
1077  }
1078  }
1079  else
1080  {
1081  $solutions =& $this->object->getSolutionValues($active_id, $pass);
1082  }
1083  }
1084 
1085 
1086  // shuffle output
1087  $terms = $this->object->getTerms();
1088  $definitions = $this->object->getDefinitions();
1089  switch ($this->object->getShuffle())
1090  {
1091  case 1:
1092  $terms = $this->object->pcArrayShuffle($terms);
1093  if (count($solutions))
1094  {
1095  $definitions = $this->sortDefinitionsBySolution($solutions);
1096  }
1097  else
1098  {
1099  $definitions = $this->object->pcArrayShuffle($definitions);
1100  }
1101  break;
1102  case 2:
1103  $terms = $this->object->pcArrayShuffle($terms);
1104  break;
1105  case 3:
1106  if (count($solutions))
1107  {
1108  $definitions = $this->sortDefinitionsBySolution($solutions);
1109  }
1110  else
1111  {
1112  $definitions = $this->object->pcArrayShuffle($definitions);
1113  }
1114  break;
1115  }
1116  $maxcount = max(count($terms), count($definitions));
1117  foreach ($definitions as $key => $definition)
1118  {
1119  if (is_object($definition))
1120  {
1121  if (strlen($definition->picture))
1122  {
1123  $template->setCurrentBlock('definition_image');
1124  $template->setVariable('ANSWER_IMAGE_URL', $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $definition->picture);
1125  $template->setVariable('ANSWER_IMAGE_ALT', (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : ilUtil::prepareFormOutput($definition->picture));
1126  $template->setVariable('ANSWER_IMAGE_TITLE', (strlen($definition->text)) ? ilUtil::prepareFormOutput($definition->text) : ilUtil::prepareFormOutput($definition->picture));
1127  $template->setVariable('URL_PREVIEW', $this->object->getImagePathWeb() . $definition->picture);
1128  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
1129  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
1130  $template->setVariable("TEXT_DEFINITION", (strlen($definition->text)) ? $this->lng->txt('definition') . ' ' . ($key+1) . ': ' . ilUtil::prepareFormOutput($definition->text) : $this->lng->txt('definition') . ' ' . ($key+1));
1131  $template->parseCurrentBlock();
1132  }
1133  else
1134  {
1135  $template->setCurrentBlock('definition_text');
1136  $template->setVariable("DEFINITION", $this->object->prepareTextareaOutput($definition->text, true));
1137  $template->parseCurrentBlock();
1138  }
1139  }
1140 
1141  $template->setCurrentBlock('option');
1142  $template->setVariable("VALUE_OPTION", 0);
1143  $template->setVariable("TEXT_OPTION", ilUtil::prepareFormOutput($this->lng->txt('please_select')));
1144  $template->parseCurrentBlock();
1145  foreach ($terms as $key => $term)
1146  {
1147  $template->setCurrentBlock('option');
1148  $template->setVariable("VALUE_OPTION", $term->identifier);
1149  $template->setVariable("TEXT_OPTION", (strlen($term->text)) ? $this->lng->txt('term') . ' ' . ($key+1) . ': ' . ilUtil::prepareFormOutput($term->text) : $this->lng->txt('term') . ' ' . ($key +1));
1150  foreach ($solutions as $solution)
1151  {
1152  if ($solution["value1"] == $term->identifier && $solution["value2"] == $definition->identifier)
1153  {
1154  $template->setVariable("SELECTED_OPTION", " selected=\"selected\"");
1155  }
1156  }
1157  $template->parseCurrentBlock();
1158  }
1159 
1160  $template->setCurrentBlock('row');
1161  $template->setVariable("TEXT_MATCHES", $this->lng->txt("matches"));
1162  if ($this->object->getEstimatedElementHeight() > 0)
1163  {
1164  $template->setVariable("ELEMENT_HEIGHT", " style=\"height: " . $this->object->getEstimatedElementHeight() . "px;\"");
1165  }
1166  $template->setVariable("QUESTION_ID", $this->object->getId());
1167  $template->setVariable("DEFINITION_ID", $definition->identifier);
1168  $template->parseCurrentBlock();
1169  }
1170  foreach ($terms as $key=>$term)
1171  {
1172  if (strlen($term->picture))
1173  {
1174  $template->setCurrentBlock('term_image');
1175  $template->setVariable('ANSWER_IMAGE_URL', $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $term->picture);
1176  $template->setVariable('ANSWER_IMAGE_ALT', (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : ilUtil::prepareFormOutput($term->picture));
1177  $template->setVariable('ANSWER_IMAGE_TITLE', (strlen($term->text)) ? ilUtil::prepareFormOutput($term->text) : ilUtil::prepareFormOutput($term->picture));
1178  $template->setVariable('URL_PREVIEW', $this->object->getImagePathWeb() . $term->picture);
1179  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
1180  $template->setVariable("TEXT_TERM", (strlen($term->text)) ? $this->lng->txt('term') . ' ' . ($key+1) . ': ' . ilUtil::prepareFormOutput($term->text) : $this->lng->txt('term') . ' ' . ($key+1));
1181  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
1182  $template->parseCurrentBlock();
1183  }
1184  else
1185  {
1186  $template->setCurrentBlock('term_text');
1187  $template->setVariable("TERM", $this->object->prepareTextareaOutput($term->text, true));
1188  $template->parseCurrentBlock();
1189  }
1190  $template->touchBlock('terms');
1191  }
1192 
1193  $questiontext = $this->object->getQuestion();
1194  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1195  $template->setVariable("TEXT_TERMS", ilUtil::prepareFormOutput($this->lng->txt('available_terms')));
1196  $template->setVariable('TEXT_SELECTION', ilUtil::prepareFormOutput($this->lng->txt('selection')));
1197 
1198  $questiontext = $this->object->getQuestion();
1199  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
1200  $questionoutput = $template->get();
1201  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1202  return $pageoutput;
1203 
1204  }
1205 
1209  function checkInput()
1210  {
1211  if ((!$_POST["title"]) or (!$_POST["author"]) or (!$_POST["question"]))
1212  {
1213  return false;
1214  }
1215  return true;
1216  }
1217 
1225  function setQuestionTabs()
1226  {
1227  global $rbacsystem, $ilTabs;
1228 
1229  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1230  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1231  $q_type = $this->object->getQuestionType();
1232 
1233  if (strlen($q_type))
1234  {
1235  $classname = $q_type . "GUI";
1236  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1237  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1238  }
1239 
1240  if ($_GET["q_id"])
1241  {
1242  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1243  {
1244  // edit page
1245  $ilTabs->addTarget("edit_page",
1246  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1247  array("edit", "insert", "exec_pg"),
1248  "", "", $force_active);
1249  }
1250 
1251  // edit page
1252  $ilTabs->addTarget("preview",
1253  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "preview"),
1254  array("preview"),
1255  "ilAssQuestionPageGUI", "", $force_active);
1256  }
1257 
1258  $force_active = false;
1259  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1260  {
1261  $url = "";
1262  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1263  // edit question properties
1264  $ilTabs->addTarget("edit_question",
1265  $url,
1266  array("editQuestion", "save", "saveEdit", "removeimageterms", "uploadterms", "removeimagedefinitions", "uploaddefinitions",
1267  "addpairs", "removepairs", "addterms", "removeterms", "adddefinitions", "removedefinitions", "originalSyncForm"),
1268  $classname, "", $force_active);
1269  }
1270 
1271  // add tab for question feedback within common class assQuestionGUI
1272  $this->addTab_QuestionFeedback($ilTabs);
1273 
1274  // add tab for question hint within common class assQuestionGUI
1275  $this->addTab_QuestionHints($ilTabs);
1276 
1277  if ($_GET["q_id"])
1278  {
1279  $ilTabs->addTarget("solution_hint",
1280  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
1281  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
1282  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
1283  ),
1284  $classname,
1285  ""
1286  );
1287  }
1288 
1289  // Assessment of questions sub menu entry
1290  if ($_GET["q_id"])
1291  {
1292  $ilTabs->addTarget("statistics",
1293  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1294  array("assessment"),
1295  $classname, "");
1296  }
1297 
1298  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
1299  {
1300  $ref_id = $_GET["calling_test"];
1301  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
1302 
1303  global $___test_express_mode;
1304 
1305  if (!$_GET['test_express_mode'] && !$___test_express_mode) {
1306  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
1307  }
1308  else {
1310  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
1311  }
1312  }
1313  else
1314  {
1315  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
1316  }
1317  }
1318 
1319  function getSpecificFeedbackOutput($active_id, $pass)
1320  {
1321  $feedback = '<table><tbody>';
1322 
1323  foreach ($this->object->getMatchingPairs() as $idx => $ans)
1324  {
1325  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
1326  $this->object->getId(), $idx
1327  );
1328  $feedback .= '<tr><td><b><i>' . $ans->definition->text . '</i></b></td><td>'. $this->lng->txt("matches") . '&nbsp;';
1329  $feedback .= '</td><td><b><i>' . $ans->term->text . '</i></b></td><td>&nbsp;</td><td>';
1330  $feedback .= $fb . '</td> </tr>';
1331  }
1332 
1333  $feedback .= '</tbody></table>';
1334  return $this->object->prepareTextareaOutput($feedback, TRUE);
1335  }
1336 
1347  {
1348  return array();
1349  }
1350 
1361  {
1362  return array('shuffle', 'element_height', 'thumb_geometry');
1363  }
1364 
1366  {
1367  $element = $form->getItemByPostvar('thumb_geometry');
1368  $_POST['thumb_geometry'] = $this->object->getThumbGeometry();
1369  $element->setValue( $this->object->getThumbGeometry() );
1370  }
1371 
1372  public function reworkFormForCorrectionMode(ilPropertyFormGUI $form)
1373  {
1374  foreach(array('definitions','terms') as $postvar)
1375  {
1377  $matching_wizardinputgui = $form->getItemByPostVar($postvar);
1378  $matching_wizardinputgui->setDisableUpload(true);
1379  $matching_wizardinputgui->setDisableActions(true);
1380  $matching_wizardinputgui->setDisableText(true);
1381  }
1382  return $form;
1383  }
1384 
1393  public function getAggregatedAnswersView($relevant_answers)
1394  {
1395  $passes = array();
1396  foreach($relevant_answers as $pass)
1397  {
1398  $passes[$pass['active_fi'].'-'.$pass['pass']] = '-';
1399  }
1400  $passcount = count($passes);
1401 
1402  foreach($relevant_answers as $pass)
1403  {
1404  $actives[$pass['active_fi']] = $pass['active_fi'];
1405  }
1406  $usercount = count($actives);
1407  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_header.html', true, true, "Modules/TestQuestionPool");
1408  $tpl->setVariable('HEADERTEXT', $this->lng->txt('overview'));
1409  $tpl->setVariable('NUMBER_OF_USERS_INFO', $this->lng->txt('number_of_users'));
1410  $tpl->setVariable('NUMBER_OF_USERS', $usercount);
1411  $tpl->setVariable('NUMBER_OF_PASSES_INFO', $this->lng->txt('number_of_passes'));
1412  $tpl->setVariable('NUMBER_OF_PASSES', $passcount);
1413 
1414  $header = $tpl->get();
1415 
1416  $variants = $this->renderVariantsView(
1417  $this->aggregateAnswerVariants($relevant_answers, $this->object->getTerms(), $this->object->getDefinitions())
1418  )->get();
1419 
1420  return $header . $variants ;
1421  }
1422 
1423  public function aggregateAnswerVariants($relevant_answers_chosen, $terms, $definitions)
1424  {
1425  $variants = array();
1426  $passdata = array();
1427  foreach ($relevant_answers_chosen as $relevant_answer)
1428  {
1429  $pass_ident = $relevant_answer['active_fi'].$relevant_answer['pass'];
1430  $answer = $passdata[$pass_ident];
1431  if (strlen($answer))
1432  {
1433  $answer_elements = explode(',', $answer);
1434  } else {
1435  $answer_elements = array();
1436  }
1437  $answer_elements[] = $relevant_answer['value1'].'.'.$relevant_answer['value2'];
1438  $passdata[$pass_ident] = implode(',',$answer_elements);
1439  }
1440  foreach($passdata as $passident => $behaviour)
1441  {
1442  $variants[$behaviour]++;
1443  }
1444  arsort($variants);
1445  return $variants;
1446  }
1447 
1448  public function renderVariantsView($aggregate)
1449  {
1450  $tpl = new ilTemplate( 'tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool" );
1451  $tpl->setVariable( 'OPTION_HEADER', $this->lng->txt( 'answer_variant' ) );
1452  $tpl->setVariable( 'COUNT_HEADER', $this->lng->txt( 'count' ) );
1453  $tpl->setVariable( 'AGGREGATION_HEADER', $this->lng->txt( 'aggregated_answers_variants' ) );
1454  foreach ($aggregate as $options => $count)
1455  {
1456  $tpl->setCurrentBlock( 'aggregaterow' );
1457  $optionstext = array();
1458  foreach (explode( ',', $options ) as $option)
1459  {
1460  $pair = explode('.',$option);
1461  if($pair[0] == -1 || $pair[1] == -1)
1462  {
1463  continue;
1464  }
1465 
1466  $term = $this->object->getTermWithIdentifier($pair[0]);
1467  $term_rep = $term->text;
1468  if($term->picture)
1469  {
1470  $term_rep .= '&nbsp;<img src="'
1471  . $this->object->getImagePathWeb()
1472  . $this->object->getThumbPrefix()
1473  . $term->picture
1474  . '" />';
1475  }
1476 
1477  $definition = $this->object->getDefinitionWithIdentifier($pair[1]);
1478  $definition_rep = $definition->text;
1479  if($definition->picture)
1480  {
1481  $definition_rep .= '&nbsp;<img src="'
1482  . $this->object->getImagePathWeb()
1483  . $this->object->getThumbPrefix()
1484  . $definition->picture
1485  . '" />';
1486  }
1487 
1488  $optionstext[] = $definition_rep. '&nbsp;-&gt;&nbsp;'. $term_rep;
1489  }
1490  $tpl->setVariable( 'OPTION', implode( '<br />', $optionstext ) );
1491  $tpl->setVariable( 'COUNT', $count );
1492  $tpl->parseCurrentBlock();
1493  }
1494 
1495  return $tpl;
1496  }
1497 
1498  private function isCorrectMatching($pair, $definition, $term)
1499  {
1500  if( !($pair->points > 0) )
1501  {
1502  return false;
1503  }
1504 
1505  if( !is_object($term) )
1506  {
1507  return false;
1508  }
1509 
1510  if( $pair->definition->identifier != $definition->identifier )
1511  {
1512  return false;
1513  }
1514 
1515  if( $pair->term->identifier != $term->identifier )
1516  {
1517  return false;
1518  }
1519 
1520  return true;
1521  }
1522 }