ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assImagemapQuestionGUI.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 include_once './Modules/Test/classes/inc.AssessmentConstants.php';
8 require_once 'Services/WebAccessChecker/classes/class.ilWACSignedPath.php';
9 
25 {
26  private $linecolor;
27 
37  public function __construct($id = -1)
38  {
39  parent::__construct();
40  include_once './Modules/TestQuestionPool/classes/class.assImagemapQuestion.php';
41  $this->object = new assImagemapQuestion();
42  if ($id >= 0) {
43  $this->object->loadFromDb($id);
44  }
45  $assessmentSetting = new ilSetting("assessment");
46  $this->linecolor = (strlen($assessmentSetting->get("imap_line_color"))) ? "#" . $assessmentSetting->get("imap_line_color") : "#FF0000";
47  }
48 
49  public function getCommand($cmd)
50  {
51  if (isset($_POST["imagemap"]) ||
52  isset($_POST["imagemap_x"]) ||
53  isset($_POST["imagemap_y"])) {
54  $this->ctrl->setCmd("getCoords");
55  $cmd = "getCoords";
56  }
57 
58  return $cmd;
59  }
60 
61  protected function deleteImage()
62  {
63  $this->object->deleteImage();
64  $this->object->saveToDb();
65  ilUtil::sendSuccess($this->lng->txt('saved_successfully'), true);
66  $this->ctrl->redirect($this, 'editQuestion');
67  }
68 
72  protected function writePostData($always = false)
73  {
74  $form = $this->buildEditForm();
75  $form->setValuesByPost();
76 
77  if (!$always && !$form->checkInput()) {
78  $this->editQuestion($form);
79  return 1;
80  }
81 
85  $this->saveTaxonomyAssignments();
86 
87  return 0;
88  }
89 
91  {
92  if ($this->ctrl->getCmd() != 'deleteImage') {
93  $this->object->flushAnswers();
94  if (is_array($_POST['image']['coords']['name'])) {
95  foreach ($_POST['image']['coords']['name'] as $idx => $name) {
96  if ($this->object->getIsMultipleChoice() && isset($_POST['image']['coords']['points_unchecked'])) {
97  $pointsUnchecked = $_POST['image']['coords']['points_unchecked'][$idx];
98  } else {
99  $pointsUnchecked = 0.0;
100  }
101 
102  $this->object->addAnswer(
103  $name,
104  $_POST['image']['coords']['points'][$idx],
105  $idx,
106  $_POST['image']['coords']['coords'][$idx],
107  $_POST['image']['coords']['shape'][$idx],
108  $pointsUnchecked
109  );
110  }
111  }
112 
113  if (strlen($_FILES['imagemapfile']['tmp_name'])) {
114  if ($this->object->getSelfAssessmentEditingMode() && $this->object->getId() < 1) {
115  $this->object->createNewQuestion();
116  }
117 
118  $this->object->uploadImagemap($form->getItemByPostVar('imagemapfile')->getShapes());
119  }
120  }
121  }
122 
124  {
125  if ($this->ctrl->getCmd() != 'deleteImage') {
126  if (strlen($_FILES['image']['tmp_name']) == 0) {
127  $this->object->setImageFilename($_POST["image_name"]);
128  }
129  }
130  if (strlen($_FILES['image']['tmp_name'])) {
131  if ($this->object->getSelfAssessmentEditingMode() && $this->object->getId() < 1) {
132  $this->object->createNewQuestion();
133  }
134  $this->object->setImageFilename($_FILES['image']['name'], $_FILES['image']['tmp_name']);
135  }
136 
137  $this->object->setIsMultipleChoice($_POST['is_multiple_choice'] == assImagemapQuestion::MODE_MULTIPLE_CHOICE);
138  }
139 
143  protected function buildEditForm()
144  {
145  $form = $this->buildBasicEditFormObject();
146 
151 
152  return $form;
153  }
154 
159  public function editQuestion(ilPropertyFormGUI $form = null)
160  {
161  if (null === $form) {
162  $form = $this->buildEditForm();
163  }
164 
165  $this->getQuestionTemplate();
166  $this->tpl->addCss('Modules/Test/templates/default/ta.css');
167 
168  $this->tpl->setVariable('QUESTION_DATA', $this->ctrl->getHTML($form));
169  }
170 
172  {
173  return $form; // Nothing to do here since selectable areas are handled in question-specific-form part
174  // due to their immediate dependency to the image. I decide to not break up the interfaces
175  // more just to support this very rare case. tl;dr: See the issue, ignore it.
176  }
177 
179  {
180  $radioGroup = new ilRadioGroupInputGUI($this->lng->txt('tst_imap_qst_mode'), 'is_multiple_choice');
181  $radioGroup->setValue($this->object->getIsMultipleChoice());
182  $modeSingleChoice = new ilRadioOption(
183  $this->lng->txt('tst_imap_qst_mode_sc'),
185  );
186  $modeMultipleChoice = new ilRadioOption(
187  $this->lng->txt('tst_imap_qst_mode_mc'),
189  );
190  $radioGroup->addOption($modeSingleChoice);
191  $radioGroup->addOption($modeMultipleChoice);
192  $form->addItem($radioGroup);
193 
194  require_once 'Modules/TestQuestionPool/classes/forms/class.ilImagemapFileInputGUI.php';
195  $image = new ilImagemapFileInputGUI($this->lng->txt('image'), 'image');
196  $image->setPointsUncheckedFieldEnabled($this->object->getIsMultipleChoice());
197  $image->setRequired(true);
198 
199  if (strlen($this->object->getImageFilename())) {
200  $image->setImage($this->object->getImagePathWeb() . $this->object->getImageFilename());
201  $image->setValue($this->object->getImageFilename());
202  $image->setAreas($this->object->getAnswers());
203  $assessmentSetting = new ilSetting("assessment");
204  $linecolor = (strlen(
205  $assessmentSetting->get("imap_line_color")
206  )) ? "\"#" . $assessmentSetting->get("imap_line_color") . "\"" : "\"#FF0000\"";
207  $image->setLineColor($linecolor);
208  $image->setImagePath($this->object->getImagePath());
209  $image->setImagePathWeb($this->object->getImagePathWeb());
210  }
211  $form->addItem($image);
212 
213  require_once 'Modules/TestQuestionPool/classes/forms/class.ilHtmlImageMapFileInputGUI.php';
214  $imagemapfile = new ilHtmlImageMapFileInputGUI($this->lng->txt('add_imagemap'), 'imagemapfile');
215  $imagemapfile->setRequired(false);
216  $form->addItem($imagemapfile);
217  return $form;
218  }
219 
220  public function addRect()
221  {
222  $this->areaEditor('rect');
223  }
224 
225  public function addCircle()
226  {
227  $this->areaEditor('circle');
228  }
229 
230  public function addPoly()
231  {
232  $this->areaEditor('poly');
233  }
234 
238  public function saveShape()
239  {
240  $coords = "";
241  switch ($_POST["shape"]) {
242  case "rect":
243  $coords = join(",", $_POST['image']['mapcoords']);
244  ilUtil::sendSuccess($this->lng->txt('msg_rect_added'), true);
245  break;
246  case "circle":
247  if (preg_match("/(\d+)\s*,\s*(\d+)\s+(\d+)\s*,\s*(\d+)/", $_POST['image']['mapcoords'][0] . " " . $_POST['image']['mapcoords'][1], $matches)) {
248  $coords = "$matches[1],$matches[2]," . (int) sqrt((($matches[3] - $matches[1]) * ($matches[3] - $matches[1])) + (($matches[4] - $matches[2]) * ($matches[4] - $matches[2])));
249  }
250  ilUtil::sendSuccess($this->lng->txt('msg_circle_added'), true);
251  break;
252  case "poly":
253  $coords = join(",", $_POST['image']['mapcoords']);
254  ilUtil::sendSuccess($this->lng->txt('msg_poly_added'), true);
255  break;
256  }
257  $this->object->addAnswer($_POST["shapetitle"], 0, count($this->object->getAnswers()), $coords, $_POST["shape"]);
258  $this->object->saveToDb();
259  $this->ctrl->redirect($this, 'editQuestion');
260  }
261 
262  public function areaEditor($shape = '')
263  {
264  $shape = (strlen($shape)) ? $shape : $_POST['shape'];
265  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
266  $this->getQuestionTemplate();
267  $this->tpl->addBlockFile("QUESTION_DATA", "question_data", "tpl.il_as_qpl_imagemap_question.html", "Modules/TestQuestionPool");
268  $coords = array();
269  if (is_array($_POST['image']['mapcoords'])) {
270  foreach ($_POST['image']['mapcoords'] as $value) {
271  array_push($coords, $value);
272  }
273  }
274  if (is_array($_POST['cmd']['areaEditor']['image'])) {
275  array_push($coords, $_POST['cmd']['areaEditor']['image'][0] . "," . $_POST['cmd']['areaEditor']['image'][1]);
276  }
277  foreach ($coords as $value) {
278  $this->tpl->setCurrentBlock("hidden");
279  $this->tpl->setVariable("HIDDEN_NAME", 'image[mapcoords][]');
280  $this->tpl->setVariable("HIDDEN_VALUE", $value);
281  $this->tpl->parseCurrentBlock();
282  }
283 
284  $this->tpl->setCurrentBlock("hidden");
285  $this->tpl->setVariable("HIDDEN_NAME", 'shape');
286  $this->tpl->setVariable("HIDDEN_VALUE", $shape);
287  $this->tpl->parseCurrentBlock();
288 
289  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
290  foreach ($this->object->answers as $index => $answer) {
291  $preview->addArea($index, $answer->getArea(), $answer->getCoords(), $answer->getAnswertext(), "", "", true, $this->linecolor);
292  }
293  $hidearea = false;
294  $disabled_save = " disabled=\"disabled\"";
295  $c = "";
296  switch ($shape) {
297  case "rect":
298  if (count($coords) == 0) {
299  ilUtil::sendInfo($this->lng->txt("rectangle_click_tl_corner"));
300  } elseif (count($coords) == 1) {
301  ilUtil::sendInfo($this->lng->txt("rectangle_click_br_corner"));
302  $preview->addPoint($preview->getAreaCount(), join(",", $coords), true, "blue");
303  } elseif (count($coords) == 2) {
304  $c = join(",", $coords);
305  $hidearea = true;
306  $disabled_save = "";
307  }
308  break;
309  case "circle":
310  if (count($coords) == 0) {
311  ilUtil::sendInfo($this->lng->txt("circle_click_center"));
312  } elseif (count($coords) == 1) {
313  ilUtil::sendInfo($this->lng->txt("circle_click_circle"));
314  $preview->addPoint($preview->getAreaCount(), join(",", $coords), true, "blue");
315  } elseif (count($coords) == 2) {
316  if (preg_match("/(\d+)\s*,\s*(\d+)\s+(\d+)\s*,\s*(\d+)/", $coords[0] . " " . $coords[1], $matches)) {
317  $c = "$matches[1],$matches[2]," . (int) sqrt((($matches[3] - $matches[1]) * ($matches[3] - $matches[1])) + (($matches[4] - $matches[2]) * ($matches[4] - $matches[2])));
318  }
319  $hidearea = true;
320  $disabled_save = "";
321  }
322  break;
323  case "poly":
324  if (count($coords) == 0) {
325  ilUtil::sendInfo($this->lng->txt("polygon_click_starting_point"));
326  } elseif (count($coords) == 1) {
327  ilUtil::sendInfo($this->lng->txt("polygon_click_next_point"));
328  $preview->addPoint($preview->getAreaCount(), implode(",", $coords), true, "blue");
329  } elseif (count($coords) > 1) {
330  ilUtil::sendInfo($this->lng->txt("polygon_click_next_or_save"));
331  $disabled_save = "";
332  $c = implode(",", $coords);
333  }
334  break;
335  }
336  if (strlen($c)) {
337  $preview->addArea($preview->getAreaCount(), $shape, $c, $_POST["shapetitle"], "", "", true, "blue");
338  }
339  $preview->createPreview();
340  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename()) . "?img=" . time();
341  if (!$hidearea) {
342  $this->tpl->setCurrentBlock("maparea");
343  $this->tpl->setVariable("IMAGE_SOURCE", "$imagepath");
344  $this->tpl->setVariable("IMAGEMAP_NAME", "image");
345  $this->tpl->parseCurrentBlock();
346  } else {
347  $this->tpl->setCurrentBlock("imagearea");
348  $this->tpl->setVariable("IMAGE_SOURCE", "$imagepath");
349  $this->tpl->setVariable("ALT_IMAGE", $this->lng->txt("imagemap"));
350  $this->tpl->parseCurrentBlock();
351  }
352 
353  if (strlen($_POST['shapetitle'])) {
354  $this->tpl->setCurrentBlock("shapetitle");
355  $this->tpl->setVariable("VALUE_SHAPETITLE", $_POST["shapetitle"]);
356  $this->tpl->parseCurrentBlock();
357  }
358 
359  $this->tpl->setVariable("TEXT_IMAGEMAP", $this->lng->txt("imagemap"));
360  $this->tpl->setVariable("TEXT_SHAPETITLE", $this->lng->txt("ass_imap_hint"));
361  $this->tpl->setVariable("CANCEL", $this->lng->txt("cancel"));
362  $this->tpl->setVariable("SAVE", $this->lng->txt("save"));
363  $this->tpl->setVariable("DISABLED_SAVE", $disabled_save);
364  switch ($shape) {
365  case "rect":
366  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addRect'));
367  break;
368  case 'circle':
369  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addCircle'));
370  break;
371  case 'poly':
372  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addPoly'));
373  break;
374  }
375  }
376 
377  public function back()
378  {
379  ilUtil::sendInfo($this->lng->txt('msg_cancel'), true);
380  $this->ctrl->redirect($this, 'editQuestion');
381  }
382 
383  // hey: prevPassSolutions - max solution pass determinations allready done, pass passed for sure
384  // hey: fixedIdentifier - changed access to passed param (lower-/uppercase issues)
385  protected function completeTestOutputFormAction($formAction, $active_id, $pass)
386  {
387  #require_once './Modules/Test/classes/class.ilObjTest.php';
388  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
389  #{
390  # $pass = ilObjTest::_getPass($active_id);
391  # $info = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
392  #}
393  #else
394  #{
395  # $info = $this->object->getUserSolutionPreferingIntermediate($active_id, NULL);
396  #}
397 
398  $info = $this->object->getTestOutputSolutions($active_id, $pass);
399 
400  if (count($info)) {
401  if (strcmp($info[0]["value1"], "") != 0) {
402  $formAction .= "&selImage=" . $info[0]["value1"];
403  }
404  }
405 
406  return $formAction;
407  }
408  // hey.
409  // hey.
410 
417  {
418  return true;
419  }
420 
434  public function getSolutionOutput(
435  $active_id,
436  $pass = null,
437  $graphicalOutput = false,
438  $result_output = false,
439  $show_question_only = true,
440  $show_feedback = false,
441  $show_correct_solution = false,
442  $show_manual_scoring = false,
443  $show_question_text = true
444  ) {
445  $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
446  $solutions = array();
447  if (($active_id > 0) && (!$show_correct_solution)) {
448  include_once "./Modules/Test/classes/class.ilObjTest.php";
449  if ((!$showsolution) && !ilObjTest::_getUsePreviousAnswers($active_id, true)) {
450  if (is_null($pass)) {
451  $pass = ilObjTest::_getPass($active_id);
452  }
453  }
454  $solutions = $this->object->getSolutionValues($active_id, $pass, !$this->getUseIntermediateSolution());
455  } else {
456  if (!$this->object->getIsMultipleChoice()) {
457  $found_index = -1;
458  $max_points = 0;
459  foreach ($this->object->answers as $index => $answer) {
460  if ($answer->getPoints() > $max_points) {
461  $max_points = $answer->getPoints();
462  $found_index = $index;
463  }
464  }
465  array_push($solutions, array("value1" => $found_index));
466  } else {
467  // take the correct solution instead of the user solution
468  foreach ($this->object->answers as $index => $answer) {
469  $points_checked = $answer->getPoints();
470  $points_unchecked = $answer->getPointsUnchecked();
471  if ($points_checked > $points_unchecked) {
472  if ($points_checked > 0) {
473  array_push($solutions, array("value1" => $index));
474  }
475  }
476  }
477  }
478  }
479  $solution_id = -1;
480  if (is_array($solutions)) {
481  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
482  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
483  foreach ($solutions as $idx => $solution_value) {
484  if (strcmp($solution_value["value1"], "") != 0) {
485  $preview->addArea($solution_value["value1"], $this->object->answers[$solution_value["value1"]]->getArea(), $this->object->answers[$solution_value["value1"]]->getCoords(), $this->object->answers[$solution_value["value1"]]->getAnswertext(), "", "", true, $this->linecolor);
486  $solution_id = $solution_value["value1"];
487  }
488  }
489  $preview->createPreview();
490  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
491  }
492 
493  // generate the question output
494  include_once "./Services/UICore/classes/class.ilTemplate.php";
495  $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output_solution.html", true, true, "Modules/TestQuestionPool");
496  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
497  $questiontext = $this->object->getQuestion();
498  if ($show_question_text == true) {
499  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
500  }
501 
502  $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
503  $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
504  $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
505  if (($active_id > 0) && (!$show_correct_solution)) {
506  if ($graphicalOutput) {
507  // output of ok/not ok icons for user entered solutions
508  $reached_points = $this->object->getReachedPoints($active_id, $pass);
509  if ($reached_points == $this->object->getMaximumPoints()) {
510  $template->setCurrentBlock("icon_ok");
511  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
512  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
513  $template->parseCurrentBlock();
514  } else {
515  $template->setCurrentBlock("icon_ok");
516  if ($reached_points > 0) {
517  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
518  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
519  } else {
520  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
521  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
522  }
523  $template->parseCurrentBlock();
524  }
525  }
526  }
527 
528  if ($show_feedback) {
529  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
530  $this->object->getId(),
531  0,
532  $solution_id
533  );
534 
535  if (strlen($fb)) {
536  $template->setCurrentBlock("feedback");
537  $template->setVariable("FEEDBACK", $fb);
538  $template->parseCurrentBlock();
539  }
540  }
541 
542  $questionoutput = $template->get();
543  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
544  if (strlen($feedback)) {
545  $cssClass = (
546  $this->hasCorrectSolution($active_id, $pass) ?
548  );
549 
550  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
551  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
552  }
553  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
554 
555  $solutionoutput = $solutiontemplate->get();
556  if (!$show_question_only) {
557  // get page object output
558  $solutionoutput = $this->getILIASPage($solutionoutput);
559  }
560  return $solutionoutput;
561  }
562 
563  public function getPreview($show_question_only = false, $showInlineFeedback = false)
564  {
565  if (is_object($this->getPreviewSession())) {
566  $user_solution = array();
567 
568  if (is_array($this->getPreviewSession()->getParticipantsSolution())) {
569  $user_solution = array_values($this->getPreviewSession()->getParticipantsSolution());
570  }
571 
572  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
573  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
574  foreach ($user_solution as $idx => $solution_value) {
575  if (strcmp($solution_value, "") != 0) {
576  $preview->addArea($solution_value, $this->object->answers[$solution_value]->getArea(), $this->object->answers[$solution_value]->getCoords(), $this->object->answers[$solution_value]->getAnswertext(), "", "", true, $this->linecolor);
577  }
578  }
579  $preview->createPreview();
580  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
581  } else {
582  $user_solution = array();
583  $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
584  }
585 
586  // generate the question output
587  include_once "./Services/UICore/classes/class.ilTemplate.php";
588  $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
589 
590  if ($this->getQuestionActionCmd() && strlen($this->getTargetGuiClass())) {
591  $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
592  } else {
593  $hrefArea = null;
594  }
595 
596  foreach ($this->object->answers as $answer_id => $answer) {
597  $parameter = "&amp;selImage=$answer_id";
598  if (is_array($user_solution) && in_array($answer_id, $user_solution)) {
599  $parameter = "&amp;remImage=$answer_id";
600  }
601 
602  if ($hrefArea) {
603  $template->setCurrentBlock("imagemap_area_href");
604  $template->setVariable("HREF_AREA", $hrefArea . $parameter);
605  $template->parseCurrentBlock();
606  }
607 
608  $template->setCurrentBlock("imagemap_area");
609  $template->setVariable("SHAPE", $answer->getArea());
610  $template->setVariable("COORDS", $answer->getCoords());
611  $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
612  $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
613  $template->parseCurrentBlock();
614  }
615  $questiontext = $this->object->getQuestion();
616  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
617  $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
618  $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
619  $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
620  $questionoutput = $template->get();
621  if (!$show_question_only) {
622  // get page object output
623  $questionoutput = $this->getILIASPage($questionoutput);
624  }
625  return $questionoutput;
626  }
627 
628  // hey: prevPassSolutions - pass will be always available from now on
629  public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false)
630  // hey.
631  {
632  if ($active_id) {
633  // hey: prevPassSolutions - obsolete due to central check
634  #$solutions = NULL;
635  #include_once "./Modules/Test/classes/class.ilObjTest.php";
636  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
637  #{
638  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
639  #}
640  $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
641  // hey.
642 
643  $userSelection = array();
644  $selectionIndex = 0;
645 
646  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
647  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
648 
649  foreach ($solutions as $idx => $solution_value) {
650  if (strlen($solution_value["value1"])) {
651  $preview->addArea($solution_value["value1"], $this->object->answers[$solution_value["value1"]]->getArea(), $this->object->answers[$solution_value["value1"]]->getCoords(), $this->object->answers[$solution_value["value1"]]->getAnswertext(), "", "", true, $this->linecolor);
652  $userSelection[$selectionIndex] = $solution_value["value1"];
653 
654  $selectionIndex = $this->object->getIsMultipleChoice() ? ++$selectionIndex : $selectionIndex;
655  }
656  }
657 
658  $preview->createPreview();
659 
660  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
661  } else {
662  $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
663  }
664 
665  // generate the question output
666  include_once "./Services/UICore/classes/class.ilTemplate.php";
667  $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
668  $this->ctrl->setParameterByClass($this->getTargetGuiClass(), "formtimestamp", time());
669  $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
670  foreach ($this->object->answers as $answer_id => $answer) {
671  $template->setCurrentBlock("imagemap_area");
672  $template->setVariable("HREF_AREA", $this->buildAreaLinkTarget($userSelection, $answer_id));
673  $template->setVariable("SHAPE", $answer->getArea());
674  $template->setVariable("COORDS", $answer->getCoords());
675  $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
676  $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
677  $template->parseCurrentBlock();
678  if ($show_feedback) {
679  if (!$this->object->getIsMultipleChoice() && count($userSelection) && current($userSelection) == $answer_id) {
680  $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
681  $this->object->getId(),
682  0,
683  $answer_id
684  );
685  if (strlen($feedback)) {
686  $template->setCurrentBlock("feedback");
687  $template->setVariable("FEEDBACK", $feedback);
688  $template->parseCurrentBlock();
689  }
690  }
691  }
692  }
693  $questiontext = $this->object->getQuestion();
694  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
695  $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
696  $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
697  $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
698  $questionoutput = $template->get();
699  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
700  return $pageoutput;
701  }
702 
703  // hey: prevPassSolutions - fixed confusing handling of not reusing, but modifying the previous solution
704  protected function buildAreaLinkTarget($currentSelection, $areaIndex)
705  {
706  $href = $this->ctrl->getLinkTargetByClass(
707  $this->getTargetGuiClass(),
708  $this->getQuestionActionCmd()
709  );
710 
712  $href,
713  $this->buildSelectionParameter($currentSelection, $areaIndex)
714  );
715 
716  return $href;
717  }
718 
719  protected function buildSelectionParameter($currentSelection, $areaIndex = null)
720  {
721  if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
722  $reuseSelection = array();
723 
724  if ($areaIndex === null) {
725  $reuseSelection = $currentSelection;
726  } elseif ($this->object->getIsMultipleChoice()) {
727  if (!in_array($areaIndex, $currentSelection)) {
728  $reuseSelection[] = $areaIndex;
729  }
730 
731  foreach (array_diff($currentSelection, array($areaIndex)) as $otherSelectedArea) {
732  $reuseSelection[] = $otherSelectedArea;
733  }
734  } else {
735  $reuseSelection[] = $areaIndex;
736  }
737 
738  $selection = assQuestion::implodeKeyValues($reuseSelection);
739  $action = 'reuseSelection';
740  } elseif ($areaIndex !== null) {
741  if (!$this->object->getIsMultipleChoice() || !in_array($areaIndex, $currentSelection)) {
742  $areaAction = 'selImage';
743  } else {
744  $areaAction = 'remImage';
745  }
746 
747  $selection = $areaIndex;
748  $action = $areaAction;
749  } else {
750  return '';
751  }
752 
753  return "{$action}={$selection}";
754  }
755  // hey.
756 
764  public function setQuestionTabs()
765  {
766  global $DIC;
767  $rbacsystem = $DIC['rbacsystem'];
768  $ilTabs = $DIC['ilTabs'];
769 
770  $ilTabs->clearTargets();
771 
772  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
773  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
774  $q_type = $this->object->getQuestionType();
775 
776  if (strlen($q_type)) {
777  $classname = $q_type . "GUI";
778  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
779  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
780  }
781 
782  if ($_GET["q_id"]) {
783  if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
784  // edit page
785  $ilTabs->addTarget(
786  "edit_page",
787  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
788  array("edit", "insert", "exec_pg"),
789  "",
790  "",
791  $force_active
792  );
793  }
794 
795  $this->addTab_QuestionPreview($ilTabs);
796  }
797 
798  $force_active = false;
799  if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
800  $url = "";
801  if ($classname) {
802  $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
803  }
804  if (array_key_exists("imagemap_x", $_POST)) {
805  $force_active = true;
806  }
807  // edit question propertiesgetPreviousSolutionValues
808  $ilTabs->addTarget(
809  "edit_question",
810  $url,
811  array("editQuestion", "save", "addArea", "addRect", "addCircle", "addPoly",
812  "uploadingImage", "uploadingImagemap", "areaEditor",
813  "saveShape", "saveEdit", "originalSyncForm"),
814  $classname,
815  "",
816  $force_active
817  );
818  }
819 
820  // add tab for question feedback within common class assQuestionGUI
821  $this->addTab_QuestionFeedback($ilTabs);
822 
823  // add tab for question hint within common class assQuestionGUI
824  $this->addTab_QuestionHints($ilTabs);
825 
826  // add tab for question's suggested solution within common class assQuestionGUI
827  $this->addTab_SuggestedSolution($ilTabs, $classname);
828 
829  // Assessment of questions sub menu entry
830  if ($_GET["q_id"]) {
831  $ilTabs->addTarget(
832  "statistics",
833  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
834  array("assessment"),
835  $classname,
836  ""
837  );
838  }
839 
840  $this->addBackTab($ilTabs);
841  }
842 
843  public function getSpecificFeedbackOutput($userSolution)
844  {
845  if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
846  return '';
847  }
848 
849  $output = '<table class="test_specific_feedback"><tbody>';
850 
851  foreach ($this->object->getAnswers() as $idx => $answer) {
852  $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
853  $this->object->getId(),
854  0,
855  $idx
856  );
857 
858  $output .= "<tr><td>{$answer->getAnswerText()}</td><td>{$feedback}</td></tr>";
859  }
860 
861  $output .= '</tbody></table>';
862 
863  return $this->object->prepareTextareaOutput($output, true);
864  }
865 
876  {
877  return array();
878  }
879 
890  {
891  return array();
892  }
893 
894  protected function renderAggregateView($answeringFequencies)
895  {
896  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
897 
898  $tpl->setCurrentBlock('headercell');
899  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
900  $tpl->parseCurrentBlock();
901 
902  $tpl->setCurrentBlock('headercell');
903  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
904  $tpl->parseCurrentBlock();
905 
906  foreach ($answeringFequencies as $answerIndex => $answeringFrequency) {
907  $tpl->setCurrentBlock('aggregaterow');
908  $tpl->setVariable('OPTION', $this->object->getAnswer($answerIndex)->getAnswerText());
909  $tpl->setVariable('COUNT', $answeringFrequency);
910  $tpl->parseCurrentBlock();
911  }
912 
913  return $tpl->get();
914  }
915 
916  protected function aggregateAnswers($givenSolutionRows, $existingAnswerOptions)
917  {
918  $answeringFequencies = array();
919 
920  foreach ($existingAnswerOptions as $answerIndex => $answerOption) {
921  $answeringFequencies[$answerIndex] = 0;
922  }
923 
924  foreach ($givenSolutionRows as $solutionRow) {
925  $answeringFequencies[$solutionRow['value1']]++;
926  }
927 
928  return $answeringFequencies;
929  }
930 
939  public function getAggregatedAnswersView($relevant_answers)
940  {
941  return $this->renderAggregateView(
942  $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
943  );
944  }
945 
947  {
948  if (!count($this->object->currentSolution)) {
949  return '';
950  }
951 
952  $button = ilLinkButton::getInstance();
953  $button->setCaption('use_previous_solution');
954 
955  $button->setUrl(ilUtil::appendUrlParameterString(
956  $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd()),
957  $this->buildSelectionParameter($this->object->currentSolution, null)
958  ));
959 
960  $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
961  $tpl->setVariable('BUTTON', $button->render());
962 
963  return $tpl->get();
964  }
965 
966  public function getAnswersFrequency($relevantAnswers, $questionIndex)
967  {
968  $agg = $this->aggregateAnswers($relevantAnswers, $this->object->getAnswers());
969 
970  $answers = array();
971 
972  foreach ($this->object->getAnswers() as $answerIndex => $ans) {
973  $answers[] = array(
974  'answer' => $ans->getAnswerText(),
975  'frequency' => $agg[$answerIndex]
976  );
977  }
978 
979  return $answers;
980  }
981 
983  {
984  require_once 'Modules/TestQuestionPool/classes/forms/class.ilImagemapCorrectionsInputGUI.php';
985  $image = new ilImagemapCorrectionsInputGUI($this->lng->txt('image'), 'image');
986  $image->setPointsUncheckedFieldEnabled($this->object->getIsMultipleChoice());
987  $image->setRequired(true);
988 
989  if (strlen($this->object->getImageFilename())) {
990  $image->setImage($this->object->getImagePathWeb() . $this->object->getImageFilename());
991  $image->setValue($this->object->getImageFilename());
992  $image->setAreas($this->object->getAnswers());
993  $assessmentSetting = new ilSetting("assessment");
994  $linecolor = (strlen(
995  $assessmentSetting->get("imap_line_color")
996  )) ? "\"#" . $assessmentSetting->get("imap_line_color") . "\"" : "\"#FF0000\"";
997  $image->setLineColor($linecolor);
998  $image->setImagePath($this->object->getImagePath());
999  $image->setImagePathWeb($this->object->getImagePathWeb());
1000  }
1001  $form->addItem($image);
1002  }
1003 
1008  {
1009  $areas = $form->getItemByPostVar('image')->getAreas();
1010 
1011  foreach ($this->object->getAnswers() as $index => $answer) {
1012  if ($this->object->getIsMultipleChoice()) {
1013  $answer->setPointsUnchecked((float) $areas[$index]->getPointsUnchecked());
1014  }
1015 
1016  $answer->setPoints((float) $areas[$index]->getPoints());
1017  }
1018  }
1019 }
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
This class represents an option in a radio group.
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
renderAggregateView($answeringFequencies)
completeTestOutputFormAction($formAction, $active_id, $pass)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
getItemByPostVar($a_post_var)
Get Item by POST variable.
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
$template
saveShape()
Saves a shape of the area editor.
This class represents a property form user interface.
$action
getAnswersFrequency($relevantAnswers, $questionIndex)
global $DIC
Definition: saml.php:7
$_GET["client_id"]
$preview
if(!array_key_exists('StateId', $_REQUEST)) $id
Class ilHtmlImageMapFileInputGUI.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
addItem($a_item)
Add Item (Property, SectionHeader).
$index
Definition: metadata.php:60
getQuestionTemplate()
get question template
getPreview($show_question_only=false, $showInlineFeedback=false)
buildAreaLinkTarget($currentSelection, $areaIndex)
$coords
Definition: example_030.php:88
populateTaxonomyFormSection(ilPropertyFormGUI $form)
Image map image preview creator.
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
buildSelectionParameter($currentSelection, $areaIndex=null)
This class represents an image map file property in a property form.
static appendUrlParameterString($a_url, $a_par, $xml_style=false)
append URL parameter string ("par1=value1&par2=value2...") to given URL string
This class represents a property in a property form.
aggregateAnswers($givenSolutionRows, $existingAnswerOptions)
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
if(isset($_POST['submit'])) $form
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
getILIASPage($html="")
Returns the ILIAS Page around a question.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
special template class to simplify handling of ITX/PEAR
static implodeKeyValues($keyValues)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
Class for image map questions.
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
static signFile($path_to_file)
Basic GUI class for assessment questions.
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
Image map question GUI representation.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
addBackTab(ilTabsGUI $ilTabs)
Interface ilGuiAnswerScoringAdjustable.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
$url
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
__construct($id=-1)
assImagemapQuestionGUI constructor
Interface ilGuiQuestionScoringAdjustable.
$info
Definition: index.php:5
static _getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
setPointsUncheckedFieldEnabled($pointsUncheckedFieldEnabled)
$_POST["username"]
setRequired($a_required)
Set Required.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
editQuestion(ilPropertyFormGUI $form=null)