ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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 $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
266 $this->getQuestionTemplate();
267
268 $editorTpl = new ilTemplate('tpl.il_as_qpl_imagemap_question.html', true, true, 'Modules/TestQuestionPool');
269
270 $coords = array();
271 if (is_array($_POST['image']['mapcoords'])) {
272 foreach ($_POST['image']['mapcoords'] as $value) {
273 array_push($coords, $value);
274 }
275 }
276 if (is_array($_POST['cmd']['areaEditor']['image'])) {
277 array_push($coords, $_POST['cmd']['areaEditor']['image'][0] . "," . $_POST['cmd']['areaEditor']['image'][1]);
278 }
279 foreach ($coords as $value) {
280 $editorTpl->setCurrentBlock("hidden");
281 $editorTpl->setVariable("HIDDEN_NAME", 'image[mapcoords][]');
282 $editorTpl->setVariable("HIDDEN_VALUE", $value);
283 $editorTpl->parseCurrentBlock();
284 }
285
286 $editorTpl->setCurrentBlock("hidden");
287 $editorTpl->setVariable("HIDDEN_NAME", 'shape');
288 $editorTpl->setVariable("HIDDEN_VALUE", $shape);
289 $editorTpl->parseCurrentBlock();
290
291 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
292 foreach ($this->object->answers as $index => $answer) {
293 $preview->addArea($index, $answer->getArea(), $answer->getCoords(), $answer->getAnswertext(), "", "", true, $this->linecolor);
294 }
295 $hidearea = false;
296 $disabled_save = " disabled=\"disabled\"";
297 $c = "";
298 switch ($shape) {
299 case "rect":
300 if (count($coords) == 0) {
301 ilUtil::sendInfo($this->lng->txt("rectangle_click_tl_corner"));
302 } elseif (count($coords) == 1) {
303 ilUtil::sendInfo($this->lng->txt("rectangle_click_br_corner"));
304 $preview->addPoint($preview->getAreaCount(), join(",", $coords), true, "blue");
305 } elseif (count($coords) == 2) {
306 $c = join(",", $coords);
307 $hidearea = true;
308 $disabled_save = "";
309 }
310 break;
311 case "circle":
312 if (count($coords) == 0) {
313 ilUtil::sendInfo($this->lng->txt("circle_click_center"));
314 } elseif (count($coords) == 1) {
315 ilUtil::sendInfo($this->lng->txt("circle_click_circle"));
316 $preview->addPoint($preview->getAreaCount(), join(",", $coords), true, "blue");
317 } elseif (count($coords) == 2) {
318 if (preg_match("/(\d+)\s*,\s*(\d+)\s+(\d+)\s*,\s*(\d+)/", $coords[0] . " " . $coords[1], $matches)) {
319 $c = "$matches[1],$matches[2]," . (int) sqrt((($matches[3] - $matches[1]) * ($matches[3] - $matches[1])) + (($matches[4] - $matches[2]) * ($matches[4] - $matches[2])));
320 }
321 $hidearea = true;
322 $disabled_save = "";
323 }
324 break;
325 case "poly":
326 if (count($coords) == 0) {
327 ilUtil::sendInfo($this->lng->txt("polygon_click_starting_point"));
328 } elseif (count($coords) == 1) {
329 ilUtil::sendInfo($this->lng->txt("polygon_click_next_point"));
330 $preview->addPoint($preview->getAreaCount(), implode(",", $coords), true, "blue");
331 } elseif (count($coords) > 1) {
332 ilUtil::sendInfo($this->lng->txt("polygon_click_next_or_save"));
333 $disabled_save = "";
334 $c = implode(",", $coords);
335 }
336 break;
337 }
338 if (strlen($c)) {
339 $preview->addArea($preview->getAreaCount(), $shape, $c, $_POST["shapetitle"], "", "", true, "blue");
340 }
341 $preview->createPreview();
342 $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename()) . "?img=" . time();
343 if (!$hidearea) {
344 $editorTpl->setCurrentBlock("maparea");
345 $editorTpl->setVariable("IMAGE_SOURCE", "$imagepath");
346 $editorTpl->setVariable("IMAGEMAP_NAME", "image");
347 $editorTpl->parseCurrentBlock();
348 } else {
349 $editorTpl->setCurrentBlock("imagearea");
350 $editorTpl->setVariable("IMAGE_SOURCE", "$imagepath");
351 $editorTpl->setVariable("ALT_IMAGE", $this->lng->txt("imagemap"));
352 $editorTpl->parseCurrentBlock();
353 }
354
355 if (strlen($_POST['shapetitle'])) {
356 $editorTpl->setCurrentBlock("shapetitle");
357 $editorTpl->setVariable("VALUE_SHAPETITLE", $_POST["shapetitle"]);
358 $editorTpl->parseCurrentBlock();
359 }
360
361 $editorTpl->setVariable("TEXT_IMAGEMAP", $this->lng->txt("imagemap"));
362 $editorTpl->setVariable("TEXT_SHAPETITLE", $this->lng->txt("ass_imap_hint"));
363 $editorTpl->setVariable("CANCEL", $this->lng->txt("cancel"));
364 $editorTpl->setVariable("SAVE", $this->lng->txt("save"));
365 $editorTpl->setVariable("DISABLED_SAVE", $disabled_save);
366 switch ($shape) {
367 case "rect":
368 $editorTpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addRect'));
369 break;
370 case 'circle':
371 $editorTpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addCircle'));
372 break;
373 case 'poly':
374 $editorTpl->setVariable("FORMACTION", $this->ctrl->getFormaction($this, 'addPoly'));
375 break;
376 }
377
378 $this->tpl->setVariable('QUESTION_DATA', $editorTpl->get());
379 }
380
381 public function back()
382 {
383 ilUtil::sendInfo($this->lng->txt('msg_cancel'), true);
384 $this->ctrl->redirect($this, 'editQuestion');
385 }
386
387 // hey: prevPassSolutions - max solution pass determinations allready done, pass passed for sure
388 // hey: fixedIdentifier - changed access to passed param (lower-/uppercase issues)
389 protected function completeTestOutputFormAction($formAction, $active_id, $pass)
390 {
391 #require_once './Modules/Test/classes/class.ilObjTest.php';
392 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
393 #{
394 # $pass = ilObjTest::_getPass($active_id);
395 # $info = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
396 #}
397 #else
398 #{
399 # $info = $this->object->getUserSolutionPreferingIntermediate($active_id, NULL);
400 #}
401
402 $info = $this->object->getTestOutputSolutions($active_id, $pass);
403
404 if (count($info)) {
405 if (strcmp($info[0]["value1"], "") != 0) {
406 $formAction .= "&selImage=" . $info[0]["value1"];
407 }
408 }
409
410 return $formAction;
411 }
412 // hey.
413 // hey.
414
421 {
422 return true;
423 }
424
438 public function getSolutionOutput(
439 $active_id,
440 $pass = null,
441 $graphicalOutput = false,
442 $result_output = false,
443 $show_question_only = true,
444 $show_feedback = false,
445 $show_correct_solution = false,
446 $show_manual_scoring = false,
447 $show_question_text = true
448 ) {
449 $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
450 $solutions = array();
451 if (($active_id > 0) && (!$show_correct_solution)) {
452 include_once "./Modules/Test/classes/class.ilObjTest.php";
453 if ((!$showsolution) && !ilObjTest::_getUsePreviousAnswers($active_id, true)) {
454 if (is_null($pass)) {
455 $pass = ilObjTest::_getPass($active_id);
456 }
457 }
458 $solutions = $this->object->getSolutionValues($active_id, $pass, !$this->getUseIntermediateSolution());
459 } else {
460 if (!$this->object->getIsMultipleChoice()) {
461 $found_index = -1;
462 $max_points = 0;
463 foreach ($this->object->answers as $index => $answer) {
464 if ($answer->getPoints() > $max_points) {
465 $max_points = $answer->getPoints();
466 $found_index = $index;
467 }
468 }
469 array_push($solutions, array("value1" => $found_index));
470 } else {
471 // take the correct solution instead of the user solution
472 foreach ($this->object->answers as $index => $answer) {
473 $points_checked = $answer->getPoints();
474 $points_unchecked = $answer->getPointsUnchecked();
475 if ($points_checked > $points_unchecked) {
476 if ($points_checked > 0) {
477 array_push($solutions, array("value1" => $index));
478 }
479 }
480 }
481 }
482 }
483 $solution_id = -1;
484 if (is_array($solutions)) {
485 include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
486 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
487 foreach ($solutions as $idx => $solution_value) {
488 $value1 = $solution_value["value1"];
489 if (
490 strcmp($value1, '') === 0 ||
491 !isset($this->object->answers[$value1])
492 ) {
493 continue;
494 }
495
497 $shape = $this->object->answers[$value1];
498 $preview->addArea(
499 $value1,
500 $shape->getArea(),
501 $shape->getCoords(),
502 $shape->getAnswertext(),
503 '',
504 '',
505 true,
506 $this->linecolor
507 );
508
509 $solution_id = $value1;
510 }
511 $preview->createPreview();
512 $imagepath = implode('', [
513 $this->object->getImagePathWeb(),
514 $preview->getPreviewFilename(
515 $this->object->getImagePath(),
516 $this->object->getImageFilename()
517 ),
518 ]);
519 }
520
521 // generate the question output
522 include_once "./Services/UICore/classes/class.ilTemplate.php";
523 $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output_solution.html", true, true, "Modules/TestQuestionPool");
524 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
525 $questiontext = $this->object->getQuestion();
526 if ($show_question_text == true) {
527 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
528 }
529
530 $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
531 $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
532 $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
533 if (($active_id > 0) && (!$show_correct_solution)) {
534 if ($graphicalOutput) {
535 // output of ok/not ok icons for user entered solutions
536 $reached_points = $this->object->getReachedPoints($active_id, $pass);
537 if ($reached_points == $this->object->getMaximumPoints()) {
538 $template->setCurrentBlock("icon_ok");
539 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
540 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
541 $template->parseCurrentBlock();
542 } else {
543 $template->setCurrentBlock("icon_ok");
544 if ($reached_points > 0) {
545 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
546 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
547 } else {
548 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
549 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
550 }
551 $template->parseCurrentBlock();
552 }
553 }
554 }
555
556 if ($show_feedback) {
557 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
558 $this->object->getId(),
559 0,
560 $solution_id
561 );
562
563 if (strlen($fb)) {
564 $template->setCurrentBlock("feedback");
565 $template->setVariable("FEEDBACK", $fb);
566 $template->parseCurrentBlock();
567 }
568 }
569
570 $questionoutput = $template->get();
571 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
572 if (strlen($feedback)) {
573 $cssClass = (
574 $this->hasCorrectSolution($active_id, $pass) ?
576 );
577
578 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
579 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
580 }
581 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
582
583 $solutionoutput = $solutiontemplate->get();
584 if (!$show_question_only) {
585 // get page object output
586 $solutionoutput = $this->getILIASPage($solutionoutput);
587 }
588 return $solutionoutput;
589 }
590
591 public function getPreview($show_question_only = false, $showInlineFeedback = false)
592 {
593 if (is_object($this->getPreviewSession())) {
594 $user_solution = array();
595
596 if (is_array($this->getPreviewSession()->getParticipantsSolution())) {
597 $user_solution = array_values($this->getPreviewSession()->getParticipantsSolution());
598 }
599
600 include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
601 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
602 foreach ($user_solution as $idx => $solution_value) {
603 if (strcmp($solution_value, "") != 0) {
604 $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);
605 }
606 }
607 $preview->createPreview();
608 $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
609 } else {
610 $user_solution = array();
611 $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
612 }
613
614 // generate the question output
615 include_once "./Services/UICore/classes/class.ilTemplate.php";
616 $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
617
618 if ($this->getQuestionActionCmd() && strlen($this->getTargetGuiClass())) {
619 $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
620 } else {
621 $hrefArea = null;
622 }
623
624 foreach ($this->object->answers as $answer_id => $answer) {
625 $parameter = "&amp;selImage=$answer_id";
626 if (is_array($user_solution) && in_array($answer_id, $user_solution)) {
627 $parameter = "&amp;remImage=$answer_id";
628 }
629
630 if ($hrefArea) {
631 $template->setCurrentBlock("imagemap_area_href");
632 $template->setVariable("HREF_AREA", $hrefArea . $parameter);
633 $template->parseCurrentBlock();
634 }
635
636 $template->setCurrentBlock("imagemap_area");
637 $template->setVariable("SHAPE", $answer->getArea());
638 $template->setVariable("COORDS", $answer->getCoords());
639 $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
640 $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
641 $template->parseCurrentBlock();
642 }
643 $questiontext = $this->object->getQuestion();
644 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
645 $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
646 $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
647 $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
648 $questionoutput = $template->get();
649 if (!$show_question_only) {
650 // get page object output
651 $questionoutput = $this->getILIASPage($questionoutput);
652 }
653 return $questionoutput;
654 }
655
656 // hey: prevPassSolutions - pass will be always available from now on
657 public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false)
658 // hey.
659 {
660 if ($active_id) {
661 // hey: prevPassSolutions - obsolete due to central check
662 #$solutions = NULL;
663 #include_once "./Modules/Test/classes/class.ilObjTest.php";
664 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
665 #{
666 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
667 #}
668 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
669 // hey.
670
671 $userSelection = array();
672 $selectionIndex = 0;
673
674 include_once "./Modules/TestQuestionPool/classes/class.ilImagemapPreview.php";
675 $preview = new ilImagemapPreview($this->object->getImagePath() . $this->object->getImageFilename());
676
677 foreach ($solutions as $idx => $solution_value) {
678 if (strlen($solution_value["value1"])) {
679 $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);
680 $userSelection[$selectionIndex] = $solution_value["value1"];
681
682 $selectionIndex = $this->object->getIsMultipleChoice() ? ++$selectionIndex : $selectionIndex;
683 }
684 }
685
686 $preview->createPreview();
687
688 $imagepath = $this->object->getImagePathWeb() . $preview->getPreviewFilename($this->object->getImagePath(), $this->object->getImageFilename());
689 } else {
690 $imagepath = $this->object->getImagePathWeb() . $this->object->getImageFilename();
691 }
692
693 // generate the question output
694 include_once "./Services/UICore/classes/class.ilTemplate.php";
695 $template = new ilTemplate("tpl.il_as_qpl_imagemap_question_output.html", true, true, "Modules/TestQuestionPool");
696 $this->ctrl->setParameterByClass($this->getTargetGuiClass(), "formtimestamp", time());
697 $hrefArea = $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd());
698 foreach ($this->object->answers as $answer_id => $answer) {
699 $template->setCurrentBlock("imagemap_area");
700 $template->setVariable("HREF_AREA", $this->buildAreaLinkTarget($userSelection, $answer_id));
701 $template->setVariable("SHAPE", $answer->getArea());
702 $template->setVariable("COORDS", $answer->getCoords());
703 $template->setVariable("ALT", ilUtil::prepareFormOutput($answer->getAnswertext()));
704 $template->setVariable("TITLE", ilUtil::prepareFormOutput($answer->getAnswertext()));
705 $template->parseCurrentBlock();
706 if ($show_feedback) {
707 if (!$this->object->getIsMultipleChoice() && count($userSelection) && current($userSelection) == $answer_id) {
708 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
709 $this->object->getId(),
710 0,
711 $answer_id
712 );
713 if (strlen($feedback)) {
714 $template->setCurrentBlock("feedback");
715 $template->setVariable("FEEDBACK", $feedback);
716 $template->parseCurrentBlock();
717 }
718 }
719 }
720 }
721 $questiontext = $this->object->getQuestion();
722 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
723 $template->setVariable("IMG_SRC", ilWACSignedPath::signFile($imagepath));
724 $template->setVariable("IMG_ALT", $this->lng->txt("imagemap"));
725 $template->setVariable("IMG_TITLE", $this->lng->txt("imagemap"));
726 $questionoutput = $template->get();
727 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
728 return $pageoutput;
729 }
730
731 // hey: prevPassSolutions - fixed confusing handling of not reusing, but modifying the previous solution
732 protected function buildAreaLinkTarget($currentSelection, $areaIndex)
733 {
734 $href = $this->ctrl->getLinkTargetByClass(
735 $this->getTargetGuiClass(),
736 $this->getQuestionActionCmd()
737 );
738
740 $href,
741 $this->buildSelectionParameter($currentSelection, $areaIndex)
742 );
743
744 return $href;
745 }
746
747 protected function buildSelectionParameter($currentSelection, $areaIndex = null)
748 {
749 if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
750 $reuseSelection = array();
751
752 if ($areaIndex === null) {
753 $reuseSelection = $currentSelection;
754 } elseif ($this->object->getIsMultipleChoice()) {
755 if (!in_array($areaIndex, $currentSelection)) {
756 $reuseSelection[] = $areaIndex;
757 }
758
759 foreach (array_diff($currentSelection, array($areaIndex)) as $otherSelectedArea) {
760 $reuseSelection[] = $otherSelectedArea;
761 }
762 } else {
763 $reuseSelection[] = $areaIndex;
764 }
765
766 $selection = assQuestion::implodeKeyValues($reuseSelection);
767 $action = 'reuseSelection';
768 } elseif ($areaIndex !== null) {
769 if (!$this->object->getIsMultipleChoice() || !in_array($areaIndex, $currentSelection)) {
770 $areaAction = 'selImage';
771 } else {
772 $areaAction = 'remImage';
773 }
774
775 $selection = $areaIndex;
776 $action = $areaAction;
777 } else {
778 return '';
779 }
780
781 return "{$action}={$selection}";
782 }
783 // hey.
784
792 public function setQuestionTabs()
793 {
794 global $DIC;
795 $rbacsystem = $DIC['rbacsystem'];
796 $ilTabs = $DIC['ilTabs'];
797
798 $ilTabs->clearTargets();
799
800 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
801 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
802 $q_type = $this->object->getQuestionType();
803
804 if (strlen($q_type)) {
805 $classname = $q_type . "GUI";
806 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
807 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
808 }
809
810 if ($_GET["q_id"]) {
811 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
812 // edit page
813 $ilTabs->addTarget(
814 "edit_page",
815 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
816 array("edit", "insert", "exec_pg"),
817 "",
818 "",
819 $force_active
820 );
821 }
822
823 $this->addTab_QuestionPreview($ilTabs);
824 }
825
826 $force_active = false;
827 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
828 $url = "";
829 if ($classname) {
830 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
831 }
832 if (array_key_exists("imagemap_x", $_POST)) {
833 $force_active = true;
834 }
835 // edit question propertiesgetPreviousSolutionValues
836 $ilTabs->addTarget(
837 "edit_question",
838 $url,
839 array("editQuestion", "save", "addArea", "addRect", "addCircle", "addPoly",
840 "uploadingImage", "uploadingImagemap", "areaEditor",
841 "saveShape", "saveEdit", "originalSyncForm"),
842 $classname,
843 "",
844 $force_active
845 );
846 }
847
848 // add tab for question feedback within common class assQuestionGUI
849 $this->addTab_QuestionFeedback($ilTabs);
850
851 // add tab for question hint within common class assQuestionGUI
852 $this->addTab_QuestionHints($ilTabs);
853
854 // add tab for question's suggested solution within common class assQuestionGUI
855 $this->addTab_SuggestedSolution($ilTabs, $classname);
856
857 // Assessment of questions sub menu entry
858 if ($_GET["q_id"]) {
859 $ilTabs->addTarget(
860 "statistics",
861 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
862 array("assessment"),
863 $classname,
864 ""
865 );
866 }
867
868 $this->addBackTab($ilTabs);
869 }
870
871 public function getSpecificFeedbackOutput($userSolution)
872 {
873 if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
874 return '';
875 }
876
877 $output = '<table class="test_specific_feedback"><tbody>';
878
879 foreach ($this->object->getAnswers() as $idx => $answer) {
880 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
881 $this->object->getId(),
882 0,
883 $idx
884 );
885
886 $output .= "<tr><td>{$answer->getAnswerText()}</td><td>{$feedback}</td></tr>";
887 }
888
889 $output .= '</tbody></table>';
890
891 return $this->object->prepareTextareaOutput($output, true);
892 }
893
904 {
905 return array();
906 }
907
918 {
919 return array();
920 }
921
922 protected function renderAggregateView($answeringFequencies)
923 {
924 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
925
926 $tpl->setCurrentBlock('headercell');
927 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
928 $tpl->parseCurrentBlock();
929
930 $tpl->setCurrentBlock('headercell');
931 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
932 $tpl->parseCurrentBlock();
933
934 foreach ($answeringFequencies as $answerIndex => $answeringFrequency) {
935 $tpl->setCurrentBlock('aggregaterow');
936 $tpl->setVariable('OPTION', $this->object->getAnswer($answerIndex)->getAnswerText());
937 $tpl->setVariable('COUNT', $answeringFrequency);
938 $tpl->parseCurrentBlock();
939 }
940
941 return $tpl->get();
942 }
943
944 protected function aggregateAnswers($givenSolutionRows, $existingAnswerOptions)
945 {
946 $answeringFequencies = array();
947
948 foreach ($existingAnswerOptions as $answerIndex => $answerOption) {
949 $answeringFequencies[$answerIndex] = 0;
950 }
951
952 foreach ($givenSolutionRows as $solutionRow) {
953 $answeringFequencies[$solutionRow['value1']]++;
954 }
955
956 return $answeringFequencies;
957 }
958
967 public function getAggregatedAnswersView($relevant_answers)
968 {
969 return $this->renderAggregateView(
970 $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
971 );
972 }
973
975 {
976 if (!count($this->object->currentSolution)) {
977 return '';
978 }
979
980 $button = ilLinkButton::getInstance();
981 $button->setCaption('use_previous_solution');
982
983 $button->setUrl(ilUtil::appendUrlParameterString(
984 $this->ctrl->getLinkTargetByClass($this->getTargetGuiClass(), $this->getQuestionActionCmd()),
985 $this->buildSelectionParameter($this->object->currentSolution, null)
986 ));
987
988 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
989 $tpl->setVariable('BUTTON', $button->render());
990
991 return $tpl->get();
992 }
993
994 public function getAnswersFrequency($relevantAnswers, $questionIndex)
995 {
996 $agg = $this->aggregateAnswers($relevantAnswers, $this->object->getAnswers());
997
998 $answers = array();
999
1000 foreach ($this->object->getAnswers() as $answerIndex => $ans) {
1001 $answers[] = array(
1002 'answer' => $ans->getAnswerText(),
1003 'frequency' => $agg[$answerIndex]
1004 );
1005 }
1006
1007 return $answers;
1008 }
1009
1011 {
1012 require_once 'Modules/TestQuestionPool/classes/forms/class.ilImagemapCorrectionsInputGUI.php';
1013 $image = new ilImagemapCorrectionsInputGUI($this->lng->txt('image'), 'image');
1014 $image->setPointsUncheckedFieldEnabled($this->object->getIsMultipleChoice());
1015 $image->setRequired(true);
1016
1017 if (strlen($this->object->getImageFilename())) {
1018 $image->setImage($this->object->getImagePathWeb() . $this->object->getImageFilename());
1019 $image->setValue($this->object->getImageFilename());
1020 $image->setAreas($this->object->getAnswers());
1021 $assessmentSetting = new ilSetting("assessment");
1022 $linecolor = (strlen(
1023 $assessmentSetting->get("imap_line_color")
1024 )) ? "\"#" . $assessmentSetting->get("imap_line_color") . "\"" : "\"#FF0000\"";
1025 $image->setLineColor($linecolor);
1026 $image->setImagePath($this->object->getImagePath());
1027 $image->setImagePathWeb($this->object->getImagePathWeb());
1028 }
1029 $form->addItem($image);
1030 }
1031
1036 {
1037 $areas = $form->getItemByPostVar('image')->getAreas();
1038
1039 foreach ($this->object->getAnswers() as $index => $answer) {
1040 if ($this->object->getIsMultipleChoice()) {
1041 $answer->setPointsUnchecked((float) $areas[$index]->getPointsUnchecked());
1042 }
1043
1044 $answer->setPoints((float) $areas[$index]->getPoints());
1045 }
1046 }
1047}
$_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.
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)
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)
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.
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)
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
if($format !==null) $name
Definition: metadata.php:230
$index
Definition: metadata.php:128
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$url
$preview
$DIC
Definition: xapitoken.php:46