ILIAS  release_7 Revision v7.30-3-g800a261c036
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 {
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
84 $this->writeAnswerSpecificPostData($form);
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
147 $this->addBasicQuestionFormProperties($form);
149 $this->populateTaxonomyFormSection($form);
150 $this->addQuestionFormCommandButtons($form);
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
167 $this->tpl->setVariable('QUESTION_DATA', $this->ctrl->getHTML($form));
168 }
169
171 {
172 return $form; // Nothing to do here since selectable areas are handled in question-specific-form part
173 // due to their immediate dependency to the image. I decide to not break up the interfaces
174 // more just to support this very rare case. tl;dr: See the issue, ignore it.
175 }
176
178 {
179 $radioGroup = new ilRadioGroupInputGUI($this->lng->txt('tst_imap_qst_mode'), 'is_multiple_choice');
180 $radioGroup->setValue($this->object->getIsMultipleChoice());
181 $modeSingleChoice = new ilRadioOption(
182 $this->lng->txt('tst_imap_qst_mode_sc'),
184 );
185 $modeMultipleChoice = new ilRadioOption(
186 $this->lng->txt('tst_imap_qst_mode_mc'),
188 );
189 $radioGroup->addOption($modeSingleChoice);
190 $radioGroup->addOption($modeMultipleChoice);
191 $form->addItem($radioGroup);
192
193 require_once 'Modules/TestQuestionPool/classes/forms/class.ilImagemapFileInputGUI.php';
194 $image = new ilImagemapFileInputGUI($this->lng->txt('image'), 'image');
195 $image->setPointsUncheckedFieldEnabled($this->object->getIsMultipleChoice());
196 $image->setRequired(true);
197
198 if (strlen($this->object->getImageFilename())) {
199 $image->setImage($this->object->getImagePathWeb() . $this->object->getImageFilename());
200 $image->setValue($this->object->getImageFilename());
201 $image->setAreas($this->object->getAnswers());
202 $assessmentSetting = new ilSetting("assessment");
203 $linecolor = (strlen(
204 $assessmentSetting->get("imap_line_color")
205 )) ? "\"#" . $assessmentSetting->get("imap_line_color") . "\"" : "\"#FF0000\"";
206 $image->setLineColor($linecolor);
207 $image->setImagePath($this->object->getImagePath());
208 $image->setImagePathWeb($this->object->getImagePathWeb());
209 }
210 $form->addItem($image);
211
212 require_once 'Modules/TestQuestionPool/classes/forms/class.ilHtmlImageMapFileInputGUI.php';
213 $imagemapfile = new ilHtmlImageMapFileInputGUI($this->lng->txt('add_imagemap'), 'imagemapfile');
214 $imagemapfile->setRequired(false);
215 $form->addItem($imagemapfile);
216 return $form;
217 }
218
219 public function addRect()
220 {
221 $this->areaEditor('rect');
222 }
223
224 public function addCircle()
225 {
226 $this->areaEditor('circle');
227 }
228
229 public function addPoly()
230 {
231 $this->areaEditor('poly');
232 }
233
237 public function saveShape()
238 {
239 $coords = "";
240 switch ($_POST["shape"]) {
242 $coords = join(",", $_POST['image']['mapcoords']);
243 ilUtil::sendSuccess($this->lng->txt('msg_rect_added'), true);
244 break;
246 if (preg_match("/(\d+)\s*,\s*(\d+)\s+(\d+)\s*,\s*(\d+)/", $_POST['image']['mapcoords'][0] . " " . $_POST['image']['mapcoords'][1], $matches)) {
247 $coords = "$matches[1],$matches[2]," . (int) sqrt((($matches[3] - $matches[1]) * ($matches[3] - $matches[1])) + (($matches[4] - $matches[2]) * ($matches[4] - $matches[2])));
248 }
249 ilUtil::sendSuccess($this->lng->txt('msg_circle_added'), true);
250 break;
252 $coords = join(",", $_POST['image']['mapcoords']);
253 ilUtil::sendSuccess($this->lng->txt('msg_poly_added'), true);
254 break;
255 }
256 $this->object->addAnswer($_POST["shapetitle"], 0, count($this->object->getAnswers()), $coords, $_POST["shape"]);
257 $this->object->saveToDb();
258 $this->ctrl->redirect($this, 'editQuestion');
259 }
260
261 public function areaEditor($shape = '')
262 {
263 $shape = (strlen($shape)) ? $shape : $_POST['shape'];
264
265 $this->getQuestionTemplate();
266
267 $editorTpl = new ilTemplate('tpl.il_as_qpl_imagemap_question.html', true, true, 'Modules/TestQuestionPool');
268
269 $coords = array();
270 if (is_array($_POST['image']['mapcoords'])) {
271 foreach ($_POST['image']['mapcoords'] as $value) {
272 array_push($coords, $value);
273 }
274 }
275 if (is_array($_POST['cmd']['areaEditor']['image'])) {
276 array_push($coords, $_POST['cmd']['areaEditor']['image'][0] . "," . $_POST['cmd']['areaEditor']['image'][1]);
277 }
278 foreach ($coords as $value) {
279 $editorTpl->setCurrentBlock("hidden");
280 $editorTpl->setVariable("HIDDEN_NAME", 'image[mapcoords][]');
281 $editorTpl->setVariable("HIDDEN_VALUE", $value);
282 $editorTpl->parseCurrentBlock();
283 }
284
285 $editorTpl->setCurrentBlock("hidden");
286 $editorTpl->setVariable("HIDDEN_NAME", 'shape');
287 $editorTpl->setVariable("HIDDEN_VALUE", $shape);
288 $editorTpl->parseCurrentBlock();
289
290 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
291 foreach ($this->object->answers as $index => $answer) {
292 $preview->addArea($index, $answer->getArea(), $answer->getCoords(), $answer->getAnswertext(), "", "", true, $this->linecolor);
293 }
294 $hidearea = false;
295 $disabled_save = " disabled=\"disabled\"";
296 $c = "";
297 switch ($shape) {
298 case "rect":
299 if (count($coords) == 0) {
300 ilUtil::sendInfo($this->lng->txt("rectangle_click_tl_corner"));
301 } elseif (count($coords) == 1) {
302 ilUtil::sendInfo($this->lng->txt("rectangle_click_br_corner"));
303 $preview->addPoint($preview->getAreaCount(), join(",", $coords), true, "blue");
304 } elseif (count($coords) == 2) {
305 $c = join(",", $coords);
306 $hidearea = true;
307 $disabled_save = "";
308 }
309 break;
310 case "circle":
311 if (count($coords) == 0) {
312 ilUtil::sendInfo($this->lng->txt("circle_click_center"));
313 } elseif (count($coords) == 1) {
314 ilUtil::sendInfo($this->lng->txt("circle_click_circle"));
315 $preview->addPoint($preview->getAreaCount(), join(",", $coords), true, "blue");
316 } elseif (count($coords) == 2) {
317 if (preg_match("/(\d+)\s*,\s*(\d+)\s+(\d+)\s*,\s*(\d+)/", $coords[0] . " " . $coords[1], $matches)) {
318 $c = "$matches[1],$matches[2]," . (int) sqrt((($matches[3] - $matches[1]) * ($matches[3] - $matches[1])) + (($matches[4] - $matches[2]) * ($matches[4] - $matches[2])));
319 }
320 $hidearea = true;
321 $disabled_save = "";
322 }
323 break;
324 case "poly":
325 if (count($coords) == 0) {
326 ilUtil::sendInfo($this->lng->txt("polygon_click_starting_point"));
327 } elseif (count($coords) == 1) {
328 ilUtil::sendInfo($this->lng->txt("polygon_click_next_point"));
329 $preview->addPoint($preview->getAreaCount(), implode(",", $coords), true, "blue");
330 } elseif (count($coords) > 1) {
331 ilUtil::sendInfo($this->lng->txt("polygon_click_next_or_save"));
332 $disabled_save = "";
333 $c = implode(",", $coords);
334 }
335 break;
336 }
337 if (strlen($c)) {
338 $preview->addArea($preview->getAreaCount(), $shape, $c, $_POST["shapetitle"], "", "", true, "blue");
339 }
340 $preview->createPreview();
341 $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename()) . "?img=" . time();
342 if (!$hidearea) {
343 $editorTpl->setCurrentBlock("maparea");
344 $editorTpl->setVariable("IMAGE_SOURCE", "$imagepath");
345 $editorTpl->setVariable("IMAGEMAP_NAME", "image");
346 $editorTpl->parseCurrentBlock();
347 } else {
348 $editorTpl->setCurrentBlock("imagearea");
349 $editorTpl->setVariable("IMAGE_SOURCE", "$imagepath");
350 $editorTpl->setVariable("ALT_IMAGE", $this->lng->txt("imagemap"));
351 $editorTpl->parseCurrentBlock();
352 }
353
354 if (strlen($_POST['shapetitle'])) {
355 $editorTpl->setCurrentBlock("shapetitle");
356 $editorTpl->setVariable("VALUE_SHAPETITLE", $_POST["shapetitle"]);
357 $editorTpl->parseCurrentBlock();
358 }
359
360 $editorTpl->setVariable("TEXT_IMAGEMAP", $this->lng->txt("imagemap"));
361 $editorTpl->setVariable("TEXT_SHAPETITLE", $this->lng->txt("ass_imap_hint"));
362 $editorTpl->setVariable("CANCEL", $this->lng->txt("cancel"));
363 $editorTpl->setVariable("SAVE", $this->lng->txt("save"));
364 $editorTpl->setVariable("DISABLED_SAVE", $disabled_save);
365 switch ($shape) {
366 case "rect":
367 $editorTpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addRect'));
368 break;
369 case 'circle':
370 $editorTpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addCircle'));
371 break;
372 case 'poly':
373 $editorTpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addPoly'));
374 break;
375 }
376
377 $this->tpl->setVariable('QUESTION_DATA', $editorTpl->get());
378 }
379
380 public function back()
381 {
382 ilUtil::sendInfo($this->lng->txt('msg_cancel'), true);
383 $this->ctrl->redirect($this, 'editQuestion');
384 }
385
386 // hey: prevPassSolutions - max solution pass determinations allready done, pass passed for sure
387 // hey: fixedIdentifier - changed access to passed param (lower-/uppercase issues)
388 protected function completeTestOutputFormAction($formAction, $active_id, $pass)
389 {
390 #require_once './Modules/Test/classes/class.ilObjTest.php';
391 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
392 #{
393 # $pass = ilObjTest::_getPass($active_id);
394 # $info = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
395 #}
396 #else
397 #{
398 # $info = $this->object->getUserSolutionPreferingIntermediate($active_id, NULL);
399 #}
400
401 $info = $this->object->getTestOutputSolutions($active_id, $pass);
402
403 if (count($info)) {
404 if (strcmp($info[0]["value1"], "") != 0) {
405 $formAction .= "&selImage=" . $info[0]["value1"];
406 }
407 }
408
409 return $formAction;
410 }
411 // hey.
412 // hey.
413
420 {
421 return true;
422 }
423
437 public function getSolutionOutput(
438 $active_id,
439 $pass = null,
440 $graphicalOutput = false,
441 $result_output = false,
442 $show_question_only = true,
443 $show_feedback = false,
444 $show_correct_solution = false,
445 $show_manual_scoring = false,
446 $show_question_text = true
447 ) {
448 $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
449 $solutions = array();
450 if (($active_id > 0) && (!$show_correct_solution)) {
451 include_once "./Modules/Test/classes/class.ilObjTest.php";
452 if ((!$showsolution) && !ilObjTest::_getUsePreviousAnswers($active_id, true)) {
453 if (is_null($pass)) {
454 $pass = ilObjTest::_getPass($active_id);
455 }
456 }
457 $solutions = $this->object->getSolutionValues($active_id, $pass, !$this->getUseIntermediateSolution());
458 } else {
459 if (!$this->object->getIsMultipleChoice()) {
460 $found_index = -1;
461 $max_points = 0;
462 foreach ($this->object->answers as $index => $answer) {
463 if ($answer->getPoints() > $max_points) {
464 $max_points = $answer->getPoints();
465 $found_index = $index;
466 }
467 }
468 array_push($solutions, array("value1" => $found_index));
469 } else {
470 // take the correct solution instead of the user solution
471 foreach ($this->object->answers as $index => $answer) {
472 $points_checked = $answer->getPoints();
473 $points_unchecked = $answer->getPointsUnchecked();
474 if ($points_checked > $points_unchecked) {
475 if ($points_checked > 0) {
476 array_push($solutions, array("value1" => $index));
477 }
478 }
479 }
480 }
481 }
482 $solution_id = -1;
483 if (is_array($solutions)) {
484 include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
485 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
486 foreach ($solutions as $idx => $solution_value) {
487 $value1 = $solution_value["value1"];
488 if (
489 strcmp($value1, '') === 0 ||
490 !isset($this->object->answers[$value1])
491 ) {
492 continue;
493 }
494
496 $shape = $this->object->answers[$value1];
497 $preview->addArea(
498 $value1,
499 $shape->getArea(),
500 $shape->getCoords(),
501 $shape->getAnswertext(),
502 '',
503 '',
504 true,
505 $this->linecolor
506 );
507
508 $solution_id = $value1;
509 }
510 $preview->createPreview();
511 $imagepath = implode('', [
512 $this->object->getImagePathWeb(),
513 $preview->getPreviewFilename(
514 $this->object->getImagePath(),
515 $this->object->getImageFilename()
516 ),
517 ]);
518 }
519
520 // generate the question output
521 include_once "./Services/UICore/classes/class.ilTemplate.php";
522 $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output_solution.html", true, true, "Modules/TestQuestionPool");
523 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
524 if ($show_question_text == true) {
525 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
526 }
527
528 $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
529 $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
530 $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
531 if (($active_id > 0) && (!$show_correct_solution)) {
532 if ($graphicalOutput) {
533 // output of ok/not ok icons for user entered solutions
534 $reached_points = $this->object->getReachedPoints($active_id, $pass);
535 if ($reached_points == $this->object->getMaximumPoints()) {
536 $template->setCurrentBlock("icon_ok");
537 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
538 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
539 $template->parseCurrentBlock();
540 } else {
541 $template->setCurrentBlock("icon_ok");
542 if ($reached_points > 0) {
543 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
544 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
545 } else {
546 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
547 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
548 }
549 $template->parseCurrentBlock();
550 }
551 }
552 }
553
554 if ($show_feedback) {
555 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
556 $this->object->getId(),
557 0,
558 $solution_id
559 );
560
561 if (strlen($fb)) {
562 $template->setCurrentBlock("feedback");
563 $template->setVariable("FEEDBACK", $fb);
564 $template->parseCurrentBlock();
565 }
566 }
567
568 $questionoutput = $template->get();
569 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
570 if (strlen($feedback)) {
571 $cssClass = (
572 $this->hasCorrectSolution($active_id, $pass) ?
574 );
575
576 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
577 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
578 }
579 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
580
581 $solutionoutput = $solutiontemplate->get();
582 if (!$show_question_only) {
583 // get page object output
584 $solutionoutput = $this->getILIASPage($solutionoutput);
585 }
586 return $solutionoutput;
587 }
588
589 public function getPreview($show_question_only = false, $showInlineFeedback = false)
590 {
591 if (is_object($this->getPreviewSession())) {
592 $user_solution = array();
593
594 if (is_array($this->getPreviewSession()->getParticipantsSolution())) {
595 $user_solution = array_values($this->getPreviewSession()->getParticipantsSolution());
596 }
597
598 include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
599 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
600 foreach ($user_solution as $idx => $solution_value) {
601 if (strcmp($solution_value, "") != 0) {
602 $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);
603 }
604 }
605 $preview->createPreview();
606 $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
607 } else {
608 $user_solution = array();
609 $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
610 }
611
612 // generate the question output
613 include_once "./Services/UICore/classes/class.ilTemplate.php";
614 $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
615
616 if ($this->getQuestionActionCmd() && strlen($this->getTargetGuiClass())) {
617 $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
618 } else {
619 $hrefArea = null;
620 }
621
622 foreach ($this->object->answers as $answer_id => $answer) {
623 $parameter = "&amp;selImage=$answer_id";
624 if (is_array($user_solution) && in_array($answer_id, $user_solution)) {
625 $parameter = "&amp;remImage=$answer_id";
626 }
627
628 if ($hrefArea) {
629 $template->setCurrentBlock("imagemap_area_href");
630 $template->setVariable("HREF_AREA", $hrefArea . $parameter);
631 $template->parseCurrentBlock();
632 }
633
634 $template->setCurrentBlock("imagemap_area");
635 $template->setVariable("SHAPE", $answer->getArea());
636 $template->setVariable("COORDS", $answer->getCoords());
637 $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
638 $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
639 $template->parseCurrentBlock();
640 }
641 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
642 $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
643 $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
644 $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
645 $questionoutput = $template->get();
646 if (!$show_question_only) {
647 // get page object output
648 $questionoutput = $this->getILIASPage($questionoutput);
649 }
650 return $questionoutput;
651 }
652
653 // hey: prevPassSolutions - pass will be always available from now on
654 public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false)
655 // hey.
656 {
657 if ($active_id) {
658 // hey: prevPassSolutions - obsolete due to central check
659 #$solutions = NULL;
660 #include_once "./Modules/Test/classes/class.ilObjTest.php";
661 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
662 #{
663 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
664 #}
665 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
666 // hey.
667
668 $userSelection = array();
669 $selectionIndex = 0;
670
671 include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
672 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
673
674 foreach ($solutions as $idx => $solution_value) {
675 if (strlen($solution_value["value1"])) {
676 $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);
677 $userSelection[$selectionIndex] = $solution_value["value1"];
678
679 $selectionIndex = $this->object->getIsMultipleChoice() ? ++$selectionIndex : $selectionIndex;
680 }
681 }
682
683 $preview->createPreview();
684
685 $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
686 } else {
687 $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
688 }
689
690 // generate the question output
691 include_once "./Services/UICore/classes/class.ilTemplate.php";
692 $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
693 $this->ctrl->setParameterByClass($this->getTargetGuiClass(), "formtimestamp", time());
694 $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
695 foreach ($this->object->answers as $answer_id => $answer) {
696 $template->setCurrentBlock("imagemap_area");
697 $template->setVariable("HREF_AREA", $this->buildAreaLinkTarget($userSelection, $answer_id));
698 $template->setVariable("SHAPE", $answer->getArea());
699 $template->setVariable("COORDS", $answer->getCoords());
700 $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
701 $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
702 $template->parseCurrentBlock();
703 if ($show_feedback) {
704 if (!$this->object->getIsMultipleChoice() && count($userSelection) && current($userSelection) == $answer_id) {
705 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
706 $this->object->getId(),
707 0,
708 $answer_id
709 );
710 if (strlen($feedback)) {
711 $template->setCurrentBlock("feedback");
712 $template->setVariable("FEEDBACK", $feedback);
713 $template->parseCurrentBlock();
714 }
715 }
716 }
717 }
718 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
719 $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
720 $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
721 $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
722 $questionoutput = $template->get();
723 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
724 return $pageoutput;
725 }
726
727 // hey: prevPassSolutions - fixed confusing handling of not reusing, but modifying the previous solution
728 protected function buildAreaLinkTarget($currentSelection, $areaIndex)
729 {
730 $href = $this->ctrl->getLinkTargetByClass(
731 $this->getTargetGuiClass(),
732 $this->getQuestionActionCmd()
733 );
734
736 $href,
737 $this->buildSelectionParameter($currentSelection, $areaIndex)
738 );
739
740 return $href;
741 }
742
743 protected function buildSelectionParameter($currentSelection, $areaIndex = null)
744 {
745 if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
746 $reuseSelection = array();
747
748 if ($areaIndex === null) {
749 $reuseSelection = $currentSelection;
750 } elseif ($this->object->getIsMultipleChoice()) {
751 if (!in_array($areaIndex, $currentSelection)) {
752 $reuseSelection[] = $areaIndex;
753 }
754
755 foreach (array_diff($currentSelection, array($areaIndex)) as $otherSelectedArea) {
756 $reuseSelection[] = $otherSelectedArea;
757 }
758 } else {
759 $reuseSelection[] = $areaIndex;
760 }
761
762 $selection = assQuestion::implodeKeyValues($reuseSelection);
763 $action = 'reuseSelection';
764 } elseif ($areaIndex !== null) {
765 if (!$this->object->getIsMultipleChoice() || !in_array($areaIndex, $currentSelection)) {
766 $areaAction = 'selImage';
767 } else {
768 $areaAction = 'remImage';
769 }
770
771 $selection = $areaIndex;
772 $action = $areaAction;
773 } else {
774 return '';
775 }
776
777 return "{$action}={$selection}";
778 }
779
780 public function getSpecificFeedbackOutput($userSolution)
781 {
782 if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
783 return '';
784 }
785
786 $output = '<table class="test_specific_feedback"><tbody>';
787
788 foreach ($this->object->getAnswers() as $idx => $answer) {
789 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
790 $this->object->getId(),
791 0,
792 $idx
793 );
794
795 $output .= "<tr><td>{$answer->getAnswerText()}</td><td>{$feedback}</td></tr>";
796 }
797
798 $output .= '</tbody></table>';
799
800 return $this->object->prepareTextareaOutput($output, true);
801 }
802
813 {
814 return array();
815 }
816
827 {
828 return array();
829 }
830
831 protected function renderAggregateView($answeringFequencies)
832 {
833 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
834
835 $tpl->setCurrentBlock('headercell');
836 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
837 $tpl->parseCurrentBlock();
838
839 $tpl->setCurrentBlock('headercell');
840 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
841 $tpl->parseCurrentBlock();
842
843 foreach ($answeringFequencies as $answerIndex => $answeringFrequency) {
844 $tpl->setCurrentBlock('aggregaterow');
845 $tpl->setVariable('OPTION', $this->object->getAnswer($answerIndex)->getAnswerText());
846 $tpl->setVariable('COUNT', $answeringFrequency);
847 $tpl->parseCurrentBlock();
848 }
849
850 return $tpl->get();
851 }
852
853 protected function aggregateAnswers($givenSolutionRows, $existingAnswerOptions)
854 {
855 $answeringFequencies = array();
856
857 foreach ($existingAnswerOptions as $answerIndex => $answerOption) {
858 $answeringFequencies[$answerIndex] = 0;
859 }
860
861 foreach ($givenSolutionRows as $solutionRow) {
862 $answeringFequencies[$solutionRow['value1']]++;
863 }
864
865 return $answeringFequencies;
866 }
867
876 public function getAggregatedAnswersView($relevant_answers)
877 {
878 return $this->renderAggregateView(
879 $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
880 );
881 }
882
884 {
885 if (!count($this->object->currentSolution)) {
886 return '';
887 }
888
889 $button = ilLinkButton::getInstance();
890 $button->setCaption('use_previous_solution');
891
892 $button->setUrl(ilUtil::appendUrlParameterString(
893 $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd()),
894 $this->buildSelectionParameter($this->object->currentSolution, null)
895 ));
896
897 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
898 $tpl->setVariable('BUTTON', $button->render());
899
900 return $tpl->get();
901 }
902
903 public function getAnswersFrequency($relevantAnswers, $questionIndex)
904 {
905 $agg = $this->aggregateAnswers($relevantAnswers, $this->object->getAnswers());
906
907 $answers = array();
908
909 foreach ($this->object->getAnswers() as $answerIndex => $ans) {
910 $answers[] = array(
911 'answer' => $ans->getAnswerText(),
912 'frequency' => $agg[$answerIndex]
913 );
914 }
915
916 return $answers;
917 }
918
920 {
921 require_once 'Modules/TestQuestionPool/classes/forms/class.ilImagemapCorrectionsInputGUI.php';
922 $image = new ilImagemapCorrectionsInputGUI($this->lng->txt('image'), 'image');
923 $image->setPointsUncheckedFieldEnabled($this->object->getIsMultipleChoice());
924 $image->setRequired(true);
925
926 if (strlen($this->object->getImageFilename())) {
927 $image->setImage($this->object->getImagePathWeb() . $this->object->getImageFilename());
928 $image->setValue($this->object->getImageFilename());
929 $image->setAreas($this->object->getAnswers());
930 $assessmentSetting = new ilSetting("assessment");
931 $linecolor = (strlen(
932 $assessmentSetting->get("imap_line_color")
933 )) ? "\"#" . $assessmentSetting->get("imap_line_color") . "\"" : "\"#FF0000\"";
934 $image->setLineColor($linecolor);
935 $image->setImagePath($this->object->getImagePath());
936 $image->setImagePathWeb($this->object->getImagePathWeb());
937 }
938 $form->addItem($image);
939 }
940
945 {
946 $areas = $form->getItemByPostVar('image')->getAreas();
947
948 foreach ($this->object->getAnswers() as $index => $answer) {
949 if ($this->object->getIsMultipleChoice()) {
950 $answer->setPointsUnchecked((float) $areas[$index]->getPointsUnchecked());
951 }
952
953 $answer->setPoints((float) $areas[$index]->getPoints());
954 }
955 }
956}
$_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.
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)
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)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
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.
hasCorrectSolution($activeId, $passIndex)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
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.
addItem($a_item)
Add Item (Property, SectionHeader).
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)
$c
Definition: cli.php:37
$preview
Definition: imgupload.php:55
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
if($format !==null) $name
Definition: metadata.php:230
$index
Definition: metadata.php:128
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc