ILIAS  release_8 Revision v8.24
class.assImagemapQuestion.php
Go to the documentation of this file.
1<?php
2
19require_once './Modules/Test/classes/inc.AssessmentConstants.php';
20
35{
36 private \ILIAS\TestQuestionPool\InternalRequestService $request; // Hate it.
37
38 // hey: prevPassSolutions - wtf is imagemap ^^
39 public $currentSolution = array();
40 // hey.
41
42 public const MODE_SINGLE_CHOICE = 0;
43 public const MODE_MULTIPLE_CHOICE = 1;
44
45 public const AVAILABLE_SHAPES = [
46 'RECT' => 'rect',
47 'CIRCLE' => 'circle',
48 'POLY' => 'poly'];
49
51 public $answers;
52
55
58
60 public $coords;
61
63 protected $is_multiple_choice = false;
64
78 public function __construct(
79 $title = "",
80 $comment = "",
81 $author = "",
82 $owner = -1,
83 $question = "",
85 ) {
87 $this->image_filename = $image_filename;
88 $this->answers = array();
89 $this->coords = array();
90
91 global $DIC;
92 $this->request = $DIC->testQuestionPool()->internal()->request();
93 }
94
101 {
102 $this->is_multiple_choice = $is_multiple_choice;
103 }
104
110 public function getIsMultipleChoice(): bool
111 {
113 }
114
121 public function isComplete(): bool
122 {
123 if (strlen($this->title)
124 && ($this->author)
125 && ($this->question)
126 && ($this->image_filename)
127 && (count($this->answers))
128 && ($this->getMaximumPoints() > 0)
129 ) {
130 return true;
131 }
132 return false;
133 }
134
144 public function saveToDb($original_id = ""): void
145 {
146 if ($original_id == '') {
147 $this->saveQuestionDataToDb();
148 } else {
150 }
153 parent::saveToDb($original_id);
154 }
155
157 {
158 global $DIC;
159 $ilDB = $DIC['ilDB'];
160 $ilDB->manipulateF(
161 "DELETE FROM qpl_a_imagemap WHERE question_fi = %s",
162 array( "integer" ),
163 array( $this->getId() )
164 );
165
166 // Anworten wegschreiben
167 foreach ($this->answers as $key => $value) {
168 $answer_obj = $this->answers[$key];
169 $answer_obj->setOrder($key);
170 $next_id = $ilDB->nextId('qpl_a_imagemap');
171 $ilDB->manipulateF(
172 "INSERT INTO qpl_a_imagemap (answer_id, question_fi, answertext, points, aorder, coords, area, points_unchecked) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
173 array( "integer", "integer", "text", "float", "integer", "text", "text", "float" ),
174 array( $next_id, $this->id, $answer_obj->getAnswertext(
175 ), $answer_obj->getPoints(), $answer_obj->getOrder(
176 ), $answer_obj->getCoords(), $answer_obj->getArea(
177 ), $answer_obj->getPointsUnchecked() )
178 );
179 }
180 }
181
183 {
184 global $DIC;
185 $ilDB = $DIC['ilDB'];
186
187 $ilDB->manipulateF(
188 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
189 array( "integer" ),
190 array( $this->getId() )
191 );
192
193 $ilDB->manipulateF(
194 "INSERT INTO " . $this->getAdditionalTableName(
195 ) . " (question_fi, image_file, is_multiple_choice) VALUES (%s, %s, %s)",
196 array( "integer", "text", 'integer' ),
197 array(
198 $this->getId(),
199 $this->image_filename,
200 (int) $this->is_multiple_choice
201 )
202 );
203 }
204
210 public function duplicate(bool $for_test = true, string $title = "", string $author = "", string $owner = "", $testObjId = null): int
211 {
212 if ($this->id <= 0) {
213 // The question has not been saved. It cannot be duplicated
214 return -1;
215 }
216 // duplicate the question in database
217 $this_id = $this->getId();
218 $thisObjId = $this->getObjId();
219
220 $clone = $this;
221 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
223 $clone->id = -1;
224
225 if ((int) $testObjId > 0) {
226 $clone->setObjId($testObjId);
227 }
228
229 if ($title) {
230 $clone->setTitle($title);
231 }
232 if ($author) {
233 $clone->setAuthor($author);
234 }
235 if ($owner) {
236 $clone->setOwner($owner);
237 }
238 if ($for_test) {
239 $clone->saveToDb($original_id);
240 } else {
241 $clone->saveToDb();
242 }
243
244 // copy question page content
245 $clone->copyPageOfQuestion($this_id);
246 // copy XHTML media objects
247 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
248 // duplicate the image
249 $clone->duplicateImage($this_id, $thisObjId);
250
251 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
252
253 return $clone->id;
254 }
255
263 public function copyObject($target_questionpool_id, $title = ""): int
264 {
265 if ($this->getId() <= 0) {
266 throw new RuntimeException('The question has not been saved. It cannot be duplicated');
267 }
268 // duplicate the question in database
269 $clone = $this;
270 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
272 $clone->id = -1;
273 $source_questionpool_id = $this->getObjId();
274 $clone->setObjId($target_questionpool_id);
275 if ($title) {
276 $clone->setTitle($title);
277 }
278 $clone->saveToDb();
279
280 // copy question page content
281 $clone->copyPageOfQuestion($original_id);
282 // copy XHTML media objects
283 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
284 // duplicate the image
285 $clone->copyImage($original_id, $source_questionpool_id);
286
287 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
288
289 return $clone->id;
290 }
291
292 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = ""): int
293 {
294 if ($this->getId() <= 0) {
295 throw new RuntimeException('The question has not been saved. It cannot be duplicated');
296 }
297
298 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
299
300 $sourceQuestionId = $this->id;
301 $sourceParentId = $this->getObjId();
302
303 // duplicate the question in database
304 $clone = $this;
305 $clone->id = -1;
306
307 $clone->setObjId($targetParentId);
308
309 if ($targetQuestionTitle) {
310 $clone->setTitle($targetQuestionTitle);
311 }
312
313 $clone->saveToDb();
314 // copy question page content
315 $clone->copyPageOfQuestion($sourceQuestionId);
316 // copy XHTML media objects
317 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
318 // duplicate the image
319 $clone->copyImage($sourceQuestionId, $sourceParentId);
320
321 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
322
323 return $clone->id;
324 }
325
326 public function duplicateImage($question_id, $objectId = null): void
327 {
328 global $DIC;
329 $ilLog = $DIC['ilLog'];
330
331 $imagepath = $this->getImagePath();
332 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
333
334 if ((int) $objectId > 0) {
335 $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
336 }
337
338 if (!file_exists($imagepath)) {
339 ilFileUtils::makeDirParents($imagepath);
340 }
341 $filename = $this->getImageFilename();
342
343 // #18755
344 if (!file_exists($imagepath_original . $filename)) {
345 $ilLog->write("Could not find an image map file when trying to duplicate image: " . $imagepath_original . $filename);
346 $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
347 $ilLog->write("Using fallback source directory:" . $imagepath_original);
348 }
349
350 if (!file_exists($imagepath_original . $filename) || !copy($imagepath_original . $filename, $imagepath . $filename)) {
351 $ilLog->write("Could not duplicate image for image map question: " . $imagepath_original . $filename);
352 }
353 }
354
355 public function copyImage($question_id, $source_questionpool): void
356 {
357 $imagepath = $this->getImagePath();
358 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
359 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
360 if (!file_exists($imagepath)) {
361 ilFileUtils::makeDirParents($imagepath);
362 }
363 $filename = $this->getImageFilename();
364 if (!copy($imagepath_original . $filename, $imagepath . $filename)) {
365 print "image could not be copied!!!! ";
366 }
367 }
368
378 public function loadFromDb($question_id): void
379 {
380 global $DIC;
381 $ilDB = $DIC['ilDB'];
382
383 $result = $ilDB->queryF(
384 "SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
385 array("integer"),
386 array($question_id)
387 );
388 if ($result->numRows() == 1) {
389 $data = $ilDB->fetchAssoc($result);
390 $this->setId($question_id);
391 $this->setObjId($data["obj_fi"]);
392 $this->setTitle((string) $data["title"]);
393 $this->setComment((string) $data["description"]);
394 $this->setOriginalId($data["original_id"]);
395 $this->setNrOfTries($data['nr_of_tries']);
396 $this->setAuthor($data["author"]);
397 $this->setPoints($data["points"]);
398 $this->setOwner($data["owner"]);
399 $this->setIsMultipleChoice($data["is_multiple_choice"] == self::MODE_MULTIPLE_CHOICE);
400 include_once("./Services/RTE/classes/class.ilRTE.php");
401 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc((string) $data["question_text"], 1));
402 $this->setImageFilename($data["image_file"]);
403
404 try {
405 $this->setLifecycle(ilAssQuestionLifecycle::getInstance($data['lifecycle']));
408 }
409
410 try {
411 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
413 }
414
415 $result = $ilDB->queryF(
416 "SELECT * FROM qpl_a_imagemap WHERE question_fi = %s ORDER BY aorder ASC",
417 array("integer"),
418 array($question_id)
419 );
420 include_once "./Modules/TestQuestionPool/classes/class.assAnswerImagemap.php";
421 if ($result->numRows() > 0) {
422 while ($data = $ilDB->fetchAssoc($result)) {
423 $image_map_question = new ASS_AnswerImagemap($data["answertext"] ?? '', $data["points"], $data["aorder"]);
424 $image_map_question->setCoords($data["coords"]);
425 $image_map_question->setArea($data["area"]);
426 $image_map_question->setPointsUnchecked($data['points_unchecked']);
427 array_push($this->answers, $image_map_question);
428 }
429 }
430 }
431 parent::loadFromDb($question_id);
432 }
433
440 public function uploadImagemap(array $shapes): int
441 {
442 $added = 0;
443
444 if (count($shapes) > 0) {
445 foreach ($shapes as $shape) {
446 $this->addAnswer($shape->getAnswertext(), 0.0, count($this->answers), $shape->getCoords(), $shape->getArea());
447 $added++;
448 }
449 }
450
451 return $added;
452 }
453
454 public function getImageFilename(): string
455 {
457 }
458
466 public function setImageFilename($image_filename, $image_tempfilename = ""): void
467 {
468 if (!empty($image_filename)) {
469 $image_filename = str_replace(" ", "_", $image_filename);
470 $this->image_filename = $image_filename;
471 }
472 if (!empty($image_tempfilename)) {
473 $imagepath = $this->getImagePath();
474 if (!file_exists($imagepath)) {
475 ilFileUtils::makeDirParents($imagepath);
476 }
477 if (!ilFileUtils::moveUploadedFile($image_tempfilename, $image_filename, $imagepath . $image_filename)) {
478 $this->ilias->raiseError("The image could not be uploaded!", $this->ilias->error_obj->MESSAGE);
479 }
480 global $DIC;
481 $ilLog = $DIC['ilLog'];
482 $ilLog->write("gespeichert: " . $imagepath . $image_filename);
483 }
484 }
485
495 public function get_imagemap_contents($href = "#"): string
496 {
497 $imagemap_contents = "<map name=\"" . $this->title . "\"> ";
498 for ($i = 0; $i < count($this->answers); $i++) {
499 $imagemap_contents .= "<area alt=\"" . $this->answers[$i]->getAnswertext() . "\" ";
500 $imagemap_contents .= "shape=\"" . $this->answers[$i]->getArea() . "\" ";
501 $imagemap_contents .= "coords=\"" . $this->answers[$i]->getCoords() . "\" ";
502 $imagemap_contents .= "href=\"$href&selimage=" . $this->answers[$i]->getOrder() . "\" /> ";
503 }
504 $imagemap_contents .= "</map>";
505 return $imagemap_contents;
506 }
507
522 public function addAnswer(
523 $answertext = "",
524 $points = 0.0,
525 $order = 0,
526 $coords = "",
527 $area = "",
528 $points_unchecked = 0.0
529 ): void {
530 include_once "./Modules/TestQuestionPool/classes/class.assAnswerImagemap.php";
531 if (array_key_exists($order, $this->answers)) {
532 // Insert answer
533 $answer = new ASS_AnswerImagemap($answertext, $points, $order, 0, -1);
534 $answer->setCoords($coords);
535 $answer->setArea($area);
536 $answer->setPointsUnchecked($points_unchecked);
537 for ($i = count($this->answers) - 1; $i >= $order; $i--) {
538 $this->answers[$i + 1] = $this->answers[$i];
539 $this->answers[$i + 1]->setOrder($i + 1);
540 }
541 $this->answers[$order] = $answer;
542 } else {
543 // Append answer
544 $answer = new ASS_AnswerImagemap($answertext, $points, count($this->answers), 0, -1);
545 $answer->setCoords($coords);
546 $answer->setArea($area);
547 $answer->setPointsUnchecked($points_unchecked);
548 array_push($this->answers, $answer);
549 }
550 }
551
561 public function getAnswerCount(): int
562 {
563 return count($this->answers);
564 }
565
577 public function getAnswer($index = 0): ?object
578 {
579 if ($index < 0) {
580 return null;
581 }
582 if (count($this->answers) < 1) {
583 return null;
584 }
585 if ($index >= count($this->answers)) {
586 return null;
587 }
588 return $this->answers[$index];
589 }
590
600 public function &getAnswers(): array
601 {
602 return $this->answers;
603 }
604
615 public function deleteArea($index = 0): void
616 {
617 if ($index < 0) {
618 return;
619 }
620 if (count($this->answers) < 1) {
621 return;
622 }
623 if ($index >= count($this->answers)) {
624 return;
625 }
626 unset($this->answers[$index]);
627 $this->answers = array_values($this->answers);
628 for ($i = 0; $i < count($this->answers); $i++) {
629 if ($this->answers[$i]->getOrder() > $index) {
630 $this->answers[$i]->setOrder($i);
631 }
632 }
633 }
634
643 public function flushAnswers(): void
644 {
645 $this->answers = array();
646 }
647
656 public function getMaximumPoints(): float
657 {
658 $points = 0;
659 foreach ($this->answers as $key => $value) {
660 if ($this->is_multiple_choice) {
661 if ($value->getPoints() > $value->getPointsUnchecked()) {
662 $points += $value->getPoints();
663 } else {
664 $points += $value->getPointsUnchecked();
665 }
666 } else {
667 if ($value->getPoints() > $points) {
668 $points = $value->getPoints();
669 }
670 }
671 }
672 return $points;
673 }
674
685 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
686 {
687 if ($returndetails) {
688 throw new ilTestException('return details not implemented for ' . __METHOD__);
689 }
690
691 global $DIC;
692 $ilDB = $DIC['ilDB'];
693
694 $found_values = array();
695 if (is_null($pass)) {
696 $pass = $this->getSolutionMaxPass($active_id);
697 }
698 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
699 while ($data = $ilDB->fetchAssoc($result)) {
700 if (strcmp($data["value1"], "") != 0) {
701 array_push($found_values, $data["value1"]);
702 }
703 }
704
705 $points = $this->calculateReachedPointsForSolution($found_values);
706
707 return $points;
708 }
709
711 {
712 $solutionData = $previewSession->getParticipantsSolution();
713
714 $reachedPoints = $this->calculateReachedPointsForSolution(is_array($solutionData) ? array_values($solutionData) : array());
715 $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
716
717 return $this->ensureNonNegativePoints($reachedPoints);
718 }
719
720 public function isAutosaveable(): bool
721 {
722 return false; // #15217
723 }
724
733 public function saveWorkingData($active_id, $pass = null, $authorized = true): bool
734 {
735 global $DIC;
736 $ilDB = $DIC['ilDB'];
737
738 if (is_null($pass)) {
739 include_once "./Modules/Test/classes/class.ilObjTest.php";
740 $pass = ilObjTest::_getPass($active_id);
741 }
742
743 $solutionSelectionChanged = false;
744
745 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$solutionSelectionChanged, $ilDB, $active_id, $pass, $authorized) {
746 if ($authorized) {
747 // remove the dummy record of the intermediate solution
748 $this->deleteDummySolutionRecord($active_id, $pass);
749
750 // delete the authorized solution and make the intermediate solution authorized (keeping timestamps)
751 $this->removeCurrentSolution($active_id, $pass, true);
752 $this->updateCurrentSolutionsAuthorization($active_id, $pass, true, true);
753
754 $solutionSelectionChanged = true;
755 } else {
756 $this->forceExistingIntermediateSolution(
757 $active_id,
758 $pass,
759 $this->is_multiple_choice
760 );
761
762 if ($this->isReuseSolutionSelectionRequest()) {
763 $selection = $this->getReuseSolutionSelectionParameter();
764
765 foreach ($selection as $selectedIndex) {
766 $this->saveCurrentSolution($active_id, $pass, (int) $selectedIndex, null, $authorized);
767 $solutionSelectionChanged = true;
768 }
769 } elseif ($this->isRemoveSolutionSelectionRequest()) {
770 $selection = $this->getRemoveSolutionSelectionParameter();
771
772 $this->deleteSolutionRecordByValues($active_id, $pass, $authorized, array(
773 'value1' => (int) $selection
774 ));
775
776 $solutionSelectionChanged = true;
777 } elseif ($this->isAddSolutionSelectionRequest()) {
778 $selection = $this->getAddSolutionSelectionParameter();
779
780 if ($this->is_multiple_choice) {
781 $this->deleteSolutionRecordByValues($active_id, $pass, $authorized, array(
782 'value1' => (int) $this->request->raw('selImage')
783 ));
784 } else {
785 $this->removeCurrentSolution($active_id, $pass, $authorized);
786 }
787
788 $this->saveCurrentSolution($active_id, $pass, $this->request->raw('selImage'), null, $authorized);
789
790 $solutionSelectionChanged = true;
791 }
792 }
793 });
794
795 require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
797 if ($solutionSelectionChanged) {
798 assQuestion::logAction($this->lng->txtlng(
799 "assessment",
800 "log_user_entered_values",
802 ), $active_id, $this->getId());
803 } else {
804 assQuestion::logAction($this->lng->txtlng(
805 "assessment",
806 "log_user_not_entered_values",
808 ), $active_id, $this->getId());
809 }
810 }
811
812 return true;
813 }
814
815 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession): void
816 {
817 $solution = $previewSession->getParticipantsSolution();
818
819 if ($this->is_multiple_choice && strlen($this->request->raw('remImage'))) {
820 unset($solution[(int) $this->request->raw('remImage')]);
821 }
822
823 if (strlen($this->request->raw('selImage'))) {
824 if (!$this->is_multiple_choice) {
825 $solution = array();
826 }
827
828 $solution[(int) $this->request->raw('selImage')] = (int) $this->request->raw('selImage');
829 }
830
831 $previewSession->setParticipantsSolution($solution);
832 }
833
834 public function syncWithOriginal(): void
835 {
836 if ($this->getOriginalId()) {
837 parent::syncWithOriginal();
838 }
839 }
840
849 public function getQuestionType(): string
850 {
851 return "assImagemapQuestion";
852 }
853
862 public function getAdditionalTableName(): string
863 {
864 return "qpl_qst_imagemap";
865 }
866
875 public function getAnswerTableName(): string
876 {
877 return "qpl_a_imagemap";
878 }
879
884 public function getRTETextWithMediaObjects(): string
885 {
886 $text = parent::getRTETextWithMediaObjects();
887 foreach ($this->answers as $index => $answer) {
888 $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), 0, $index);
889 }
890 return $text;
891 }
892
896 public function setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass): int
897 {
898 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
899
900 $solution = $this->getSolutionValues($active_id, $pass);
901
902 $i = 1;
903 foreach ($this->getAnswers() as $id => $answer) {
904 $worksheet->setCell($startrow + $i, 0, $answer->getArea() . ": " . $answer->getCoords());
905 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
906
907 $cellValue = 0;
908 foreach ($solution as $solIndex => $sol) {
909 if ($sol['value1'] == $id) {
910 $cellValue = 1;
911 break;
912 }
913 }
914
915 $worksheet->setCell($startrow + $i, 2, $cellValue);
916
917 $i++;
918 }
919
920 return $startrow + $i + 1;
921 }
922
926 public function deleteImage(): void
927 {
928 $file = $this->getImagePath() . $this->getImageFilename();
929 @unlink($file);
930 $this->flushAnswers();
931 $this->image_filename = "";
932 }
933
937 public function toJSON(): string
938 {
939 include_once("./Services/RTE/classes/class.ilRTE.php");
940 $result = array();
941 $result['id'] = $this->getId();
942 $result['type'] = (string) $this->getQuestionType();
943 $result['title'] = $this->getTitleForHTMLOutput();
944 $result['question'] = $this->formatSAQuestion($this->getQuestion());
945 $result['nr_of_tries'] = $this->getNrOfTries();
946 $result['shuffle'] = $this->getShuffle();
947 $result['is_multiple'] = $this->getIsMultipleChoice();
948 $result['feedback'] = array(
949 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
950 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
951 );
952 $result['image'] = $this->getImagePathWeb() . $this->getImageFilename();
953
954 $answers = array();
955 $order = 0;
956 foreach ($this->getAnswers() as $key => $answer_obj) {
957 array_push($answers, array(
958 "answertext" => (string) $answer_obj->getAnswertext(),
959 "points" => (float) $answer_obj->getPoints(),
960 "points_unchecked" => (float) $answer_obj->getPointsUnchecked(),
961 "order" => $order,
962 "coords" => $answer_obj->getCoords(),
963 "state" => $answer_obj->getState(),
964 "area" => $answer_obj->getArea(),
965 "feedback" => $this->formatSAQuestion(
966 $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), 0, $key)
967 )
968 ));
969 $order++;
970 }
971 $result['answers'] = $answers;
972
973 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
974 $result['mobs'] = $mobs;
975
976 return json_encode($result);
977 }
978
983 protected function calculateReachedPointsForSolution($found_values): float
984 {
985 if ($found_values == null) {
986 $found_values = [];
987 }
988 $points = 0;
989 if (count($found_values) > 0) {
990 foreach ($this->answers as $key => $answer) {
991 if (in_array($key, $found_values)) {
992 $points += $answer->getPoints();
993 } elseif ($this->getIsMultipleChoice()) {
994 $points += $answer->getPointsUnchecked();
995 }
996 }
997 return $points;
998 }
999 return $points;
1000 }
1001
1010 public function getOperators($expression): array
1011 {
1013 }
1014
1019 public function getExpressionTypes(): array
1020 {
1021 return array(
1026 );
1027 }
1028
1037 public function getUserQuestionResult($active_id, $pass): ilUserQuestionResult
1038 {
1040 global $DIC;
1041 $ilDB = $DIC['ilDB'];
1042 $result = new ilUserQuestionResult($this, $active_id, $pass);
1043
1044 $maxStep = $this->lookupMaxStep($active_id, $pass);
1045
1046 if ($maxStep !== null) {
1047 $data = $ilDB->queryF(
1048 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1049 array("integer", "integer", "integer", "integer"),
1050 array($active_id, $pass, $this->getId(), $maxStep)
1051 );
1052 } else {
1053 $data = $ilDB->queryF(
1054 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step IS NULL",
1055 array("integer", "integer", "integer"),
1056 array($active_id, $pass, $this->getId())
1057 );
1058 }
1059
1060 while ($row = $ilDB->fetchAssoc($data)) {
1061 $result->addKeyValue($row["value1"], $row["value1"]);
1062 }
1063
1064 $points = $this->calculateReachedPoints($active_id, $pass);
1065 $max_points = $this->getMaximumPoints();
1066
1067 $result->setReachedPercentage(($points / $max_points) * 100);
1068
1069 return $result;
1070 }
1071
1079 public function getAvailableAnswerOptions($index = null)
1080 {
1081 if ($index !== null) {
1082 return $this->getAnswer($index);
1083 } else {
1084 return $this->getAnswers();
1085 }
1086 }
1087
1088 // hey: prevPassSolutions - wtf is imagemap ^^
1089 public function getTestOutputSolutions($activeId, $pass): array
1090 {
1091 $solution = parent::getTestOutputSolutions($activeId, $pass);
1092
1093 $this->currentSolution = array();
1094 foreach ($solution as $record) {
1095 $this->currentSolution[] = $record['value1'];
1096 }
1097
1098 return $solution;
1099 }
1101 {
1102 if (!$this->isAddSolutionSelectionRequest()) {
1103 return null;
1104 }
1105
1106 return $this->request->raw('selImage');
1107 }
1108 protected function isAddSolutionSelectionRequest(): bool
1109 {
1110 if (!$this->request->isset("selImage")) {
1111 return false;
1112 }
1113
1114 if (!strlen($this->request->raw('selImage'))) {
1115 return false;
1116 }
1117
1118 return true;
1119 }
1121 {
1122 if (!$this->isRemoveSolutionSelectionRequest()) {
1123 return null;
1124 }
1125
1126 return $this->request->raw('remImage');
1127 }
1128 protected function isRemoveSolutionSelectionRequest(): bool
1129 {
1130 if (!$this->is_multiple_choice) {
1131 return false;
1132 }
1133
1134 if (!$this->request->isset("remImage")) {
1135 return false;
1136 }
1137
1138 if (!strlen($this->request->raw('remImage'))) {
1139 return false;
1140 }
1141
1142 return true;
1143 }
1144 protected function getReuseSolutionSelectionParameter(): ?array
1145 {
1146 if (!$this->isReuseSolutionSelectionRequest()) {
1147 return null;
1148 }
1149
1150 return assQuestion::explodeKeyValues($this->request->raw("reuseSelection"));
1151 }
1152 protected function isReuseSolutionSelectionRequest(): bool
1153 {
1154 if (!$this->getTestPresentationConfig()->isPreviousPassSolutionReuseAllowed()) {
1155 return false;
1156 }
1157
1158 if (!$this->request->isset("reuseSelection")) {
1159 return false;
1160 }
1161
1162 if (!strlen($this->request->raw("reuseSelection"))) {
1163 return false;
1164 }
1165
1166 if (!preg_match('/\d(,\d)*/', $this->request->raw("reuseSelection"))) {
1167 return false;
1168 }
1169
1170 return true;
1171 }
1172 // hey.
1173}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$filename
Definition: buildRTE.php:78
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
getQuestionType()
Returns the question type of the question.
setIsMultipleChoice($is_multiple_choice)
Set true if the Imagemapquestion is a multiplechoice Question.
uploadImagemap(array $shapes)
Uploads an image map and takes over the areas.
flushAnswers()
Deletes all answers.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
toJSON()
Returns a JSON representation of the question.
duplicateImage($question_id, $objectId=null)
setImageFilename($image_filename, $image_tempfilename="")
Sets the image file name.
getAnswer($index=0)
Returns an answer.
getTestOutputSolutions($activeId, $pass)
getAnswerTableName()
Returns the name of the answer table in the database.
ILIAS TestQuestionPool InternalRequestService $request
setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass)
{}
getExpressionTypes()
Get all available expression types for a specific question.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
copyObject($target_questionpool_id, $title="")
Copies an assImagemapQuestion object.
deleteImage()
Deletes the image file.
calculateReachedPointsForSolution($found_values)
isComplete()
Returns true, if a imagemap question is complete for use.
getOperators($expression)
Get all available operations for a specific question.
deleteArea($index=0)
Deletes an answer.
& getAnswers()
Returns the answer array.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
duplicate(bool $for_test=true, string $title="", string $author="", string $owner="", $testObjId=null)
Duplicates an assImagemapQuestion.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
copyImage($question_id, $source_questionpool)
loadFromDb($question_id)
Loads a assImagemapQuestion object from a database.
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $image_filename="")
assImagemapQuestion constructor
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
saveToDb($original_id="")
Saves an assImagemapQuestion object to a database.
addAnswer( $answertext="", $points=0.0, $order=0, $coords="", $area="", $points_unchecked=0.0)
Adds a possible answer for a imagemap question.
getAnswerCount()
Returns the number of answers.
get_imagemap_contents($href="#")
Gets the imagemap file contents.
getIsMultipleChoice()
Returns true, if the imagemap question is a multiplechoice question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
Abstract basic class which is to be extended by the concrete assessment question type classes.
float $points
The maximum available points for the question.
setOriginalId(?int $original_id)
string $question
The question text.
static logAction(string $logtext, int $active_id, int $question_id)
setId(int $id=-1)
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
setQuestion(string $question="")
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
static _getOriginalId(int $question_id)
ILIAS DI LoggingServices $ilLog
saveQuestionDataToDb(int $original_id=-1)
setAuthor(string $author="")
static explodeKeyValues(string $keyValues)
setComment(string $comment="")
setObjId(int $obj_id=0)
setOwner(int $owner=-1)
setNrOfTries(int $a_nr_of_tries)
setLifecycle(ilAssQuestionLifecycle $lifecycle)
setTitle(string $title="")
setPoints(float $points)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setCell($a_row, $a_col, $a_value, $datatype=null)
setBold(string $a_coords)
Set cell(s) to bold.
getColumnCoord(int $a_col)
Get column "name" from number.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static _getMobsOfObject(string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: feed.php:28
$mobs
Definition: imgupload.php:70
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$index
Definition: metadata.php:145
$i
Definition: metadata.php:41
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
header include for all ilias files.