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