ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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(), join($coords, ","), true, "blue");
329  } elseif (count($coords) > 1) {
330  ilUtil::sendInfo($this->lng->txt("polygon_click_next_or_save"));
331  $disabled_save = "";
332  $c = join($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 
424  public function getSolutionOutput(
425  $active_id,
426  $pass = null,
427  $graphicalOutput = false,
428  $result_output = false,
429  $show_question_only = true,
430  $show_feedback = false,
431  $show_correct_solution = false,
432  $show_manual_scoring = false,
433  $show_question_text = true
434  ) {
435  $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
436  $solutions = array();
437  if (($active_id > 0) && (!$show_correct_solution)) {
438  include_once "./Modules/Test/classes/class.ilObjTest.php";
439  if ((!$showsolution) && !ilObjTest::_getUsePreviousAnswers($active_id, true)) {
440  if (is_null($pass)) {
441  $pass = ilObjTest::_getPass($active_id);
442  }
443  }
444  $solutions =&$this->object->getSolutionValues($active_id, $pass);
445  } else {
446  if (!$this->object->getIsMultipleChoice()) {
447  $found_index = -1;
448  $max_points = 0;
449  foreach ($this->object->answers as $index => $answer) {
450  if ($answer->getPoints() > $max_points) {
451  $max_points = $answer->getPoints();
452  $found_index = $index;
453  }
454  }
455  array_push($solutions, array("value1" => $found_index));
456  } else {
457  // take the correct solution instead of the user solution
458  foreach ($this->object->answers as $index => $answer) {
459  $points_checked = $answer->getPoints();
460  $points_unchecked = $answer->getPointsUnchecked();
461  if ($points_checked > $points_unchecked) {
462  if ($points_checked > 0) {
463  array_push($solutions, array("value1" => $index));
464  }
465  }
466  }
467  }
468  }
469  $solution_id = -1;
470  if (is_array($solutions)) {
471  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
472  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
473  foreach ($solutions as $idx => $solution_value) {
474  if (strcmp($solution_value["value1"], "") != 0) {
475  $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);
476  $solution_id = $solution_value["value1"];
477  }
478  }
479  $preview->createPreview();
480  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
481  }
482 
483  // generate the question output
484  include_once "./Services/UICore/classes/class.ilTemplate.php";
485  $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output_solution.html", true, true, "Modules/TestQuestionPool");
486  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
487  $questiontext = $this->object->getQuestion();
488  if ($show_question_text==true) {
489  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
490  }
491 
492  $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
493  $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
494  $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
495  if (($active_id > 0) && (!$show_correct_solution)) {
496  if ($graphicalOutput) {
497  // output of ok/not ok icons for user entered solutions
498  $reached_points = $this->object->getReachedPoints($active_id, $pass);
499  if ($reached_points == $this->object->getMaximumPoints()) {
500  $template->setCurrentBlock("icon_ok");
501  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
502  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
503  $template->parseCurrentBlock();
504  } else {
505  $template->setCurrentBlock("icon_ok");
506  if ($reached_points > 0) {
507  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
508  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
509  } else {
510  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
511  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
512  }
513  $template->parseCurrentBlock();
514  }
515  }
516  }
517 
518  if ($show_feedback) {
519  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
520  $this->object->getId(),
521  $solution_id
522  );
523 
524  if (strlen($fb)) {
525  $template->setCurrentBlock("feedback");
526  $template->setVariable("FEEDBACK", $fb);
527  $template->parseCurrentBlock();
528  }
529  }
530 
531  $questionoutput = $template->get();
532  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
533  if (strlen($feedback)) {
534  $cssClass = (
535  $this->hasCorrectSolution($active_id, $pass) ?
537  );
538 
539  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
540  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
541  }
542  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
543 
544  $solutionoutput = $solutiontemplate->get();
545  if (!$show_question_only) {
546  // get page object output
547  $solutionoutput = $this->getILIASPage($solutionoutput);
548  }
549  return $solutionoutput;
550  }
551 
552  public function getPreview($show_question_only = false, $showInlineFeedback = false)
553  {
554  if (is_object($this->getPreviewSession())) {
555  $user_solution = array();
556 
557  if (is_array($this->getPreviewSession()->getParticipantsSolution())) {
558  $user_solution = array_values($this->getPreviewSession()->getParticipantsSolution());
559  }
560 
561  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
562  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
563  foreach ($user_solution as $idx => $solution_value) {
564  if (strcmp($solution_value, "") != 0) {
565  $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);
566  }
567  }
568  $preview->createPreview();
569  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
570  } else {
571  $user_solution = array();
572  $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
573  }
574 
575  // generate the question output
576  include_once "./Services/UICore/classes/class.ilTemplate.php";
577  $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
578 
579  if ($this->getQuestionActionCmd() && strlen($this->getTargetGuiClass())) {
580  $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
581  } else {
582  $hrefArea = null;
583  }
584 
585  foreach ($this->object->answers as $answer_id => $answer) {
586  $parameter = "&amp;selImage=$answer_id";
587  if (is_array($user_solution) && in_array($answer_id, $user_solution)) {
588  $parameter = "&amp;remImage=$answer_id";
589  }
590 
591  if ($hrefArea) {
592  $template->setCurrentBlock("imagemap_area_href");
593  $template->setVariable("HREF_AREA", $hrefArea . $parameter);
594  $template->parseCurrentBlock();
595  }
596 
597  $template->setCurrentBlock("imagemap_area");
598  $template->setVariable("SHAPE", $answer->getArea());
599  $template->setVariable("COORDS", $answer->getCoords());
600  $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
601  $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
602  $template->parseCurrentBlock();
603  }
604  $questiontext = $this->object->getQuestion();
605  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
606  $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
607  $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
608  $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
609  $questionoutput = $template->get();
610  if (!$show_question_only) {
611  // get page object output
612  $questionoutput = $this->getILIASPage($questionoutput);
613  }
614  return $questionoutput;
615  }
616 
617  // hey: prevPassSolutions - pass will be always available from now on
618  public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false)
619  // hey.
620  {
621  if ($active_id) {
622  // hey: prevPassSolutions - obsolete due to central check
623  #$solutions = NULL;
624  #include_once "./Modules/Test/classes/class.ilObjTest.php";
625  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
626  #{
627  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
628  #}
629  $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
630  // hey.
631 
632  $userSelection = array();
633  $selectionIndex = 0;
634 
635  include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
636  $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
637 
638  foreach ($solutions as $idx => $solution_value) {
639  if (strlen($solution_value["value1"])) {
640  $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);
641  $userSelection[$selectionIndex] = $solution_value["value1"];
642 
643  $selectionIndex = $this->object->getIsMultipleChoice() ? ++$selectionIndex : $selectionIndex;
644  }
645  }
646 
647  $preview->createPreview();
648 
649  $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
650  } else {
651  $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
652  }
653 
654  // generate the question output
655  include_once "./Services/UICore/classes/class.ilTemplate.php";
656  $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
657  $this->ctrl->setParameterByClass($this->getTargetGuiClass(), "formtimestamp", time());
658  $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
659  foreach ($this->object->answers as $answer_id => $answer) {
660  $template->setCurrentBlock("imagemap_area");
661  $template->setVariable("HREF_AREA", $this->buildAreaLinkTarget($userSelection, $answer_id));
662  $template->setVariable("SHAPE", $answer->getArea());
663  $template->setVariable("COORDS", $answer->getCoords());
664  $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
665  $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
666  $template->parseCurrentBlock();
667  if ($show_feedback) {
668  if (!$this->object->getIsMultipleChoice() && count($userSelection) && current($userSelection) == $answer_id) {
669  $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
670  $this->object->getId(),
671  $answer_id
672  );
673  if (strlen($feedback)) {
674  $template->setCurrentBlock("feedback");
675  $template->setVariable("FEEDBACK", $feedback);
676  $template->parseCurrentBlock();
677  }
678  }
679  }
680  }
681  $questiontext = $this->object->getQuestion();
682  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
683  $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
684  $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
685  $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
686  $questionoutput = $template->get();
687  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
688  return $pageoutput;
689  }
690 
691  // hey: prevPassSolutions - fixed confusing handling of not reusing, but modifying the previous solution
692  protected function buildAreaLinkTarget($currentSelection, $areaIndex)
693  {
694  $href = $this->ctrl->getLinkTargetByClass(
695  $this->getTargetGuiClass(),
696  $this->getQuestionActionCmd()
697  );
698 
700  $href,
701  $this->buildSelectionParameter($currentSelection, $areaIndex)
702  );
703 
704  return $href;
705  }
706 
707  protected function buildSelectionParameter($currentSelection, $areaIndex = null)
708  {
709  if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
710  $reuseSelection = array();
711 
712  if ($areaIndex === null) {
713  $reuseSelection = $currentSelection;
714  } elseif ($this->object->getIsMultipleChoice()) {
715  if (!in_array($areaIndex, $currentSelection)) {
716  $reuseSelection[] = $areaIndex;
717  }
718 
719  foreach (array_diff($currentSelection, array($areaIndex)) as $otherSelectedArea) {
720  $reuseSelection[] = $otherSelectedArea;
721  }
722  } else {
723  $reuseSelection[] = $areaIndex;
724  }
725 
726  $selection = assQuestion::implodeKeyValues($reuseSelection);
727  $action = 'reuseSelection';
728  } elseif ($areaIndex !== null) {
729  if (!$this->object->getIsMultipleChoice() || !in_array($areaIndex, $currentSelection)) {
730  $areaAction = 'selImage';
731  } else {
732  $areaAction = 'remImage';
733  }
734 
735  $selection = $areaIndex;
736  $action = $areaAction;
737  } else {
738  return '';
739  }
740 
741  return "{$action}={$selection}";
742  }
743  // hey.
744 
752  public function setQuestionTabs()
753  {
754  global $rbacsystem, $ilTabs;
755 
756  $ilTabs->clearTargets();
757 
758  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
759  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
760  $q_type = $this->object->getQuestionType();
761 
762  if (strlen($q_type)) {
763  $classname = $q_type . "GUI";
764  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
765  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
766  }
767 
768  if ($_GET["q_id"]) {
769  if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
770  // edit page
771  $ilTabs->addTarget(
772  "edit_page",
773  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
774  array("edit", "insert", "exec_pg"),
775  "",
776  "",
777  $force_active
778  );
779  }
780 
781  $this->addTab_QuestionPreview($ilTabs);
782  }
783 
784  $force_active = false;
785  if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
786  $url = "";
787  if ($classname) {
788  $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
789  }
790  if (array_key_exists("imagemap_x", $_POST)) {
791  $force_active = true;
792  }
793  // edit question propertiesgetPreviousSolutionValues
794  $ilTabs->addTarget(
795  "edit_question",
796  $url,
797  array("editQuestion", "save", "addArea", "addRect", "addCircle", "addPoly",
798  "uploadingImage", "uploadingImagemap", "areaEditor",
799  "saveShape", "saveEdit", "originalSyncForm"),
800  $classname,
801  "",
802  $force_active
803  );
804  }
805 
806  // add tab for question feedback within common class assQuestionGUI
807  $this->addTab_QuestionFeedback($ilTabs);
808 
809  // add tab for question hint within common class assQuestionGUI
810  $this->addTab_QuestionHints($ilTabs);
811 
812  // add tab for question's suggested solution within common class assQuestionGUI
813  $this->addTab_SuggestedSolution($ilTabs, $classname);
814 
815  // Assessment of questions sub menu entry
816  if ($_GET["q_id"]) {
817  $ilTabs->addTarget(
818  "statistics",
819  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
820  array("assessment"),
821  $classname,
822  ""
823  );
824  }
825 
826  $this->addBackTab($ilTabs);
827  }
828 
829  public function getSpecificFeedbackOutput($active_id, $pass)
830  {
831  if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists(array_values($this->object->getAnswers()))) {
832  return '';
833  }
834 
835  $output = '<table class="test_specific_feedback"><tbody>';
836 
837  foreach ($this->object->getAnswers() as $idx => $answer) {
838  $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
839  $this->object->getId(),
840  $idx
841  );
842 
843  $output .= "<tr><td>{$answer->getAnswerText()}</td><td>{$feedback}</td></tr>";
844  }
845 
846  $output .= '</tbody></table>';
847 
848  return $this->object->prepareTextareaOutput($output, true);
849  }
850 
861  {
862  return array();
863  }
864 
875  {
876  return array();
877  }
878 
879  protected function renderAggregateView($answeringFequencies)
880  {
881  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
882 
883  $tpl->setCurrentBlock('headercell');
884  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
885  $tpl->parseCurrentBlock();
886 
887  $tpl->setCurrentBlock('headercell');
888  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
889  $tpl->parseCurrentBlock();
890 
891  foreach ($answeringFequencies as $answerIndex => $answeringFrequency) {
892  $tpl->setCurrentBlock('aggregaterow');
893  $tpl->setVariable('OPTION', $this->object->getAnswer($answerIndex)->getAnswerText());
894  $tpl->setVariable('COUNT', $answeringFrequency);
895  $tpl->parseCurrentBlock();
896  }
897 
898  return $tpl->get();
899  }
900 
901  protected function aggregateAnswers($givenSolutionRows, $existingAnswerOptions)
902  {
903  $answeringFequencies = array();
904 
905  foreach ($existingAnswerOptions as $answerIndex => $answerOption) {
906  $answeringFequencies[$answerIndex] = 0;
907  }
908 
909  foreach ($givenSolutionRows as $solutionRow) {
910  $answeringFequencies[$solutionRow['value1']]++;
911  }
912 
913  return $answeringFequencies;
914  }
915 
924  public function getAggregatedAnswersView($relevant_answers)
925  {
926  return $this->renderAggregateView(
927  $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
928  );
929  }
930 
932  {
933  if (!count($this->object->currentSolution)) {
934  return '';
935  }
936 
937  $button = ilLinkButton::getInstance();
938  $button->setCaption('use_previous_solution');
939 
940  $button->setUrl(ilUtil::appendUrlParameterString(
941  $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd()),
942  $this->buildSelectionParameter($this->object->currentSolution, null)
943  ));
944 
945  $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
946  $tpl->setVariable('BUTTON', $button->render());
947 
948  return $tpl->get();
949  }
950 }
static sendSuccess($a_info="", $a_keep=false)
Send Success Message to Screen.
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.
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
$_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.
getSpecificFeedbackOutput($active_id, $pass)
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)
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
This class represents an image map file property in a property form.
if($format !==null) $name
Definition: metadata.php:146
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.
Create styles array
The data for the language used.
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
Image map question GUI representation.
Create new PHPExcel object
obj_idprivate
addBackTab(ilTabsGUI $ilTabs)
Interface ilGuiAnswerScoringAdjustable.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
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...
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
__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.
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)