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
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7include_once './Modules/Test/classes/inc.AssessmentConstants.php';
8require_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
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 {
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}
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Image map question GUI representation.
editQuestion(ilPropertyFormGUI $form=null)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
saveShape()
Saves a shape of the area editor.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
aggregateAnswers($givenSolutionRows, $existingAnswerOptions)
buildSelectionParameter($currentSelection, $areaIndex=null)
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getAnswersFrequency($relevantAnswers, $questionIndex)
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
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.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
buildAreaLinkTarget($currentSelection, $areaIndex)
renderAggregateView($answeringFequencies)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
__construct($id=-1)
assImagemapQuestionGUI constructor
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getPreview($show_question_only=false, $showInlineFeedback=false)
completeTestOutputFormAction($formAction, $active_id, $pass)
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
Class for image map questions.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
addBackTab(ilTabsGUI $ilTabs)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
static implodeKeyValues($keyValues)
Class ilHtmlImageMapFileInputGUI.
This class represents an image map file property in a property form.
Image map image preview creator.
static getInstance()
Factory.
static _getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
This class represents a property form user interface.
getItemByPostVar($a_post_var)
Get Item by POST variable.
This class represents a property in a property form.
This class represents an option in a radio group.
ILIAS Setting Class.
special template class to simplify handling of ITX/PEAR
static appendUrlParameterString($a_url, $a_par, $xml_style=false)
append URL parameter string ("par1=value1&par2=value2...") to given URL string
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
static signFile($path_to_file)
$template
$action
$coords
Definition: example_030.php:88
if(!array_key_exists('StateId', $_REQUEST)) $id
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$index
Definition: metadata.php:60
$info
Definition: index.php:5
$url
if(isset($_POST['submit'])) $form
global $DIC
Definition: saml.php:7
$preview