ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.assMultipleChoice.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.assQuestion.php';
5require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7require_once './Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
10require_once 'Modules/TestQuestionPool/interfaces/interface.ilAssSpecificFeedbackOptionLabelProvider.php';
11
28{
37
47
51
53 protected $thumb_size;
54
59 {
60 $this->isSingleline = $isSingleline;
61 }
62
66 public function getIsSingleline()
67 {
69 }
70
74 public function setLastChange($lastChange)
75 {
76 $this->lastChange = $lastChange;
77 }
78
82 public function getLastChange()
83 {
84 return $this->lastChange;
85 }
86
101 public function __construct(
102 $title = "",
103 $comment = "",
104 $author = "",
105 $owner = -1,
106 $question = "",
108 )
109 {
110 parent::__construct($title, $comment, $author, $owner, $question);
111 $this->output_type = $output_type;
112 $this->thumb_size = 150;
113 $this->answers = array();
114 $this->shuffle = 1;
115 }
116
123 function isComplete()
124 {
125 if (strlen($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
126 {
127 return true;
128 }
129 else
130 {
131 return false;
132 }
133 }
134
140 public function saveToDb($original_id = "")
141 {
145
146 $this->ensureNoInvalidObligation($this->getId());
147 parent::saveToDb($original_id);
148 }
149
153 protected function rebuildThumbnails()
154 {
155 if ($this->isSingleline && ($this->getThumbSize()))
156 {
157 foreach ($this->getAnswers() as $answer)
158 {
159 if (strlen($answer->getImage()))
160 {
161 $this->generateThumbForFile($this->getImagePath(), $answer->getImage());
162 }
163 }
164 }
165 }
166
170 public function getThumbPrefix()
171 {
172 return "thumb.";
173 }
174
179 protected function generateThumbForFile($path, $file)
180 {
182 if (@file_exists($filename))
183 {
184 $thumbpath = $path . $this->getThumbPrefix() . $file;
185 $path_info = @pathinfo($filename);
186 $ext = "";
187 switch (strtoupper($path_info['extension']))
188 {
189 case 'PNG':
190 $ext = 'PNG';
191 break;
192 case 'GIF':
193 $ext = 'GIF';
194 break;
195 default:
196 $ext = 'JPEG';
197 break;
198 }
199 ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbSize());
200 }
201 }
202
208 public function loadFromDb($question_id)
209 {
210 global $ilDB;
211 $hasimages = 0;
212
213 $result = $ilDB->queryF("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",
214 array("integer"),
215 array($question_id)
216 );
217 if ($result->numRows() == 1)
218 {
219 $data = $ilDB->fetchAssoc($result);
220 $this->setId($question_id);
221 $this->setObjId($data["obj_fi"]);
222 $this->setTitle($data["title"]);
223 $this->setNrOfTries($data['nr_of_tries']);
224 $this->setComment($data["description"]);
225 $this->setOriginalId($data["original_id"]);
226 $this->setAuthor($data["author"]);
227 $this->setPoints($data["points"]);
228 $this->setOwner($data["owner"]);
229 include_once("./Services/RTE/classes/class.ilRTE.php");
230 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
231 $shuffle = (is_null($data['shuffle'])) ? true : $data['shuffle'];
232 $this->setShuffle($shuffle);
233 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
234 $this->setThumbSize($data['thumb_size']);
235 $this->isSingleline = ($data['allow_images']) ? false : true;
236 $this->lastChange = $data['tstamp'];
237 $this->feedback_setting = $data['feedback_setting'];
238
239 try
240 {
241 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
242 }
244 {
245 }
246 }
247
248 $result = $ilDB->queryF("SELECT * FROM qpl_a_mc WHERE question_fi = %s ORDER BY aorder ASC",
249 array('integer'),
250 array($question_id)
251 );
252 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
253 if ($result->numRows() > 0)
254 {
255 while ($data = $ilDB->fetchAssoc($result))
256 {
257 $imagefilename = $this->getImagePath() . $data["imagefile"];
258 if (!@file_exists($imagefilename))
259 {
260 $data["imagefile"] = "";
261 }
262 include_once("./Services/RTE/classes/class.ilRTE.php");
263 $data["answertext"] = ilRTE::_replaceMediaObjectImageSrc($data["answertext"], 1);
264 array_push($this->answers, new ASS_AnswerMultipleResponseImage($data["answertext"], $data["points"], $data["aorder"], $data["points_unchecked"], $data["imagefile"]));
265 }
266 }
267
268 parent::loadFromDb($question_id);
269 }
270
274 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
275 {
276 if ($this->id <= 0)
277 {
278 // The question has not been saved. It cannot be duplicated
279 return;
280 }
281 // duplicate the question in database
282 $this_id = $this->getId();
283 $thisObjId = $this->getObjId();
284
285 $clone = $this;
286 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
288 $clone->id = -1;
289
290 if( (int)$testObjId > 0 )
291 {
292 $clone->setObjId($testObjId);
293 }
294
295 if ($title)
296 {
297 $clone->setTitle($title);
298 }
299
300 if ($author)
301 {
302 $clone->setAuthor($author);
303 }
304 if ($owner)
305 {
306 $clone->setOwner($owner);
307 }
308
309 if ($for_test)
310 {
311 $clone->saveToDb($original_id);
312 }
313 else
314 {
315 $clone->saveToDb();
316 }
317
318 // copy question page content
319 $clone->copyPageOfQuestion($this_id);
320 // copy XHTML media objects
321 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
322 // duplicate the images
323 $clone->duplicateImages($this_id, $thisObjId);
324
325 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
326
327 return $clone->id;
328 }
329
333 public function copyObject($target_questionpool_id, $title = "")
334 {
335 if ($this->id <= 0)
336 {
337 // The question has not been saved. It cannot be duplicated
338 return;
339 }
340 // duplicate the question in database
341 $clone = $this;
342 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
344 $clone->id = -1;
345 $source_questionpool_id = $this->getObjId();
346 $clone->setObjId($target_questionpool_id);
347 if ($title)
348 {
349 $clone->setTitle($title);
350 }
351 $clone->saveToDb();
352 // copy question page content
353 $clone->copyPageOfQuestion($original_id);
354 // copy XHTML media objects
355 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
356 // duplicate the image
357 $clone->copyImages($original_id, $source_questionpool_id);
358
359 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
360
361 return $clone->id;
362 }
363
364 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
365 {
366 if ($this->id <= 0)
367 {
368 // The question has not been saved. It cannot be duplicated
369 return;
370 }
371
372 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
373
374 $sourceQuestionId = $this->id;
375 $sourceParentId = $this->getObjId();
376
377 // duplicate the question in database
378 $clone = $this;
379 $clone->id = -1;
380
381 $clone->setObjId($targetParentId);
382
383 if ($targetQuestionTitle)
384 {
385 $clone->setTitle($targetQuestionTitle);
386 }
387
388 $clone->saveToDb();
389 // copy question page content
390 $clone->copyPageOfQuestion($sourceQuestionId);
391 // copy XHTML media objects
392 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
393 // duplicate the image
394 $clone->copyImages($sourceQuestionId, $sourceParentId);
395
396 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
397
398 return $clone->id;
399 }
400
407 public function getOutputType()
408 {
409 return $this->output_type;
410 }
411
420 {
421 $this->output_type = $output_type;
422 }
423
437 public function addAnswer(
438 $answertext = "",
439 $points = 0.0,
440 $points_unchecked = 0.0,
441 $order = 0,
442 $answerimage = ""
443 )
444 {
445 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
446 if (array_key_exists($order, $this->answers))
447 {
448 // insert answer
449 $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, $order, $points_unchecked, $answerimage);
450 $newchoices = array();
451 for ($i = 0; $i < $order; $i++)
452 {
453 array_push($newchoices, $this->answers[$i]);
454 }
455 array_push($newchoices, $answer);
456 for ($i = $order; $i < count($this->answers); $i++)
457 {
458 $changed = $this->answers[$i];
459 $changed->setOrder($i+1);
460 array_push($newchoices, $changed);
461 }
462 $this->answers = $newchoices;
463 }
464 else
465 {
466 // add answer
467 $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, count($this->answers), $points_unchecked, $answerimage);
468 array_push($this->answers, $answer);
469 }
470 }
471
478 public function getAnswerCount()
479 {
480 return count($this->answers);
481 }
482
491 public function getAnswer($index = 0)
492 {
493 if ($index < 0) return NULL;
494 if (count($this->answers) < 1) return NULL;
495 if ($index >= count($this->answers)) return NULL;
496
497 return $this->answers[$index];
498 }
499
507 public function deleteAnswer($index = 0)
508 {
509 if ($index < 0) return;
510 if (count($this->answers) < 1) return;
511 if ($index >= count($this->answers)) return;
512 $answer = $this->answers[$index];
513 if (strlen($answer->getImage())) $this->deleteImage($answer->getImage());
514 unset($this->answers[$index]);
515 $this->answers = array_values($this->answers);
516 for ($i = 0; $i < count($this->answers); $i++)
517 {
518 if ($this->answers[$i]->getOrder() > $index)
519 {
520 $this->answers[$i]->setOrder($i);
521 }
522 }
523 }
524
530 public function flushAnswers()
531 {
532 $this->answers = array();
533 }
534
540 public function getMaximumPoints()
541 {
542 $points = 0;
543 $allpoints = 0;
544 foreach ($this->answers as $key => $value)
545 {
546 if ($value->getPoints() > $value->getPointsUnchecked())
547 {
548 $allpoints += $value->getPoints();
549 }
550 else
551 {
552 $allpoints += $value->getPointsUnchecked();
553 }
554 }
555 return $allpoints;
556 }
557
569 public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
570 {
571 if( $returndetails )
572 {
573 throw new ilTestException('return details not implemented for '.__METHOD__);
574 }
575
576 global $ilDB;
577
578 $found_values = array();
579 if (is_null($pass))
580 {
581 $pass = $this->getSolutionMaxPass($active_id);
582 }
583 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
584 while ($data = $ilDB->fetchAssoc($result))
585 {
586 if (strcmp($data["value1"], "") != 0)
587 {
588 array_push($found_values, $data["value1"]);
589 }
590 }
591
592 $points = $this->calculateReachedPointsForSolution($found_values, $active_id);
593
594 return $points;
595 }
596
605 public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
606 {
608 global $ilDB;
609
610 if (is_null($pass))
611 {
612 include_once "./Modules/Test/classes/class.ilObjTest.php";
613 $pass = ilObjTest::_getPass($active_id);
614 }
615
616 $entered_values = 0;
617
618 $this->getProcessLocker()->requestUserSolutionUpdateLock();
619
620 $this->removeCurrentSolution($active_id, $pass, $authorized);
621
622 $solutionSubmit = $this->getSolutionSubmit();
623
624 foreach($solutionSubmit as $value)
625 {
626 if (strlen($value))
627 {
628 $this->saveCurrentSolution($active_id, $pass, $value, null, $authorized);
629 $entered_values++;
630 }
631 }
632
633 $this->getProcessLocker()->releaseUserSolutionUpdateLock();
634
635 if ($entered_values)
636 {
637 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
639 {
640 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
641 }
642 }
643 else
644 {
645 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
647 {
648 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
649 }
650 }
651
652 return true;
653 }
654
655 public function saveAdditionalQuestionDataToDb()
656 {
658 global $ilDB;
659 $oldthumbsize = 0;
660 if ($this->isSingleline && ($this->getThumbSize()))
661 {
662 // get old thumbnail size
663 $result = $ilDB->queryF( "SELECT thumb_size FROM " . $this->getAdditionalTableName(
664 ) . " WHERE question_fi = %s",
665 array( "integer" ),
666 array( $this->getId() )
667 );
668 if ($result->numRows() == 1)
669 {
670 $data = $ilDB->fetchAssoc( $result );
671 $oldthumbsize = $data['thumb_size'];
672 }
673 }
674
675 if (!$this->isSingleline)
676 {
677 ilUtil::delDir( $this->getImagePath() );
678 }
679
680 // save additional data
681 $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
682 array( "integer" ),
683 array( $this->getId() )
684 );
685
686 $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName()
687 . " (question_fi, shuffle, allow_images, thumb_size) VALUES (%s, %s, %s, %s)",
688 array( "integer", "text", "text", "integer" ),
689 array(
690 $this->getId(),
691 $this->getShuffle(),
692 ($this->isSingleline) ? "0" : "1",
693 (strlen( $this->getThumbSize() ) == 0) ? null : $this->getThumbSize()
694 )
695 );
696 }
697
698 public function saveAnswerSpecificDataToDb()
699 {
701 global $ilDB;
702 $ilDB->manipulateF( "DELETE FROM qpl_a_mc WHERE question_fi = %s",
703 array( 'integer' ),
704 array( $this->getId() )
705 );
706
707 foreach ($this->answers as $key => $value)
708 {
709 $answer_obj = $this->answers[$key];
710 $next_id = $ilDB->nextId( 'qpl_a_mc' );
711 $ilDB->manipulateF( "INSERT INTO qpl_a_mc (answer_id, question_fi, answertext, points, points_unchecked, aorder, imagefile, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
712 array( 'integer', 'integer', 'text', 'float', 'float', 'integer', 'text', 'integer' ),
713 array(
714 $next_id,
715 $this->getId(),
716 ilRTE::_replaceMediaObjectImageSrc( $answer_obj->getAnswertext(), 0 ),
717 $answer_obj->getPoints(),
718 $answer_obj->getPointsUnchecked(),
719 $answer_obj->getOrder(),
720 $answer_obj->getImage(),
721 time()
722 )
723 );
724 }
725 $this->rebuildThumbnails();
726 }
727
735 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
736 {
737 // nothing to rework!
738 }
739
741 {
742 if ($this->getOriginalId())
743 {
744 $this->syncImages();
745 parent::syncWithOriginal();
746 }
747 }
748
754 public function getQuestionType()
755 {
756 return "assMultipleChoice";
757 }
758
764 public function getAdditionalTableName()
765 {
766 return "qpl_qst_mc";
767 }
768
774 public function getAnswerTableName()
775 {
776 return "qpl_a_mc";
777 }
778
786 public function setImageFile($image_filename, $image_tempfilename = "")
787 {
788 $result = 0;
789 if (!empty($image_tempfilename))
790 {
791 $image_filename = str_replace(" ", "_", $image_filename);
792 $imagepath = $this->getImagePath();
793 if (!file_exists($imagepath))
794 {
795 ilUtil::makeDirParents($imagepath);
796 }
797 if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
798 {
799 $result = 2;
800 }
801 else
802 {
803 include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
804 $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
805 if (!preg_match("/^image/", $mimetype))
806 {
807 unlink($imagepath . $image_filename);
808 $result = 1;
809 }
810 else
811 {
812 // create thumbnail file
813 if ($this->isSingleline && ($this->getThumbSize()))
814 {
815 $this->generateThumbForFile($imagepath, $image_filename);
816 }
817 }
818 }
819 }
820 return $result;
821 }
822
828 protected function deleteImage($image_filename)
829 {
830 $imagepath = $this->getImagePath();
831 @unlink($imagepath . $image_filename);
832 $thumbpath = $imagepath . $this->getThumbPrefix() . $image_filename;
833 @unlink($thumbpath);
834 }
835
836 function duplicateImages($question_id, $objectId = null)
837 {
839 global $ilLog;
840
841 $imagepath = $this->getImagePath();
842 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
843
844 if( (int)$objectId > 0 )
845 {
846 $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
847 }
848
849 foreach ($this->answers as $answer)
850 {
851 $filename = $answer->getImage();
852 if (strlen($filename))
853 {
854 if (!file_exists($imagepath))
855 {
856 ilUtil::makeDirParents($imagepath);
857 }
858 if (!@copy($imagepath_original . $filename, $imagepath . $filename))
859 {
860 $ilLog->warning(sprintf(
861 "Could not clone source image '%s' to '%s' (srcQuestionId: %s|tgtQuestionId: %s|srcParentObjId: %s|tgtParentObjId: %s)",
862 $imagepath_original . $filename, $imagepath . $filename,
863 $question_id, $this->id, $objectId, $this->obj_id
864 ));
865 }
866 if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
867 {
868 if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
869 {
870 $ilLog->warning(sprintf(
871 "Could not clone thumbnail source image '%s' to '%s' (srcQuestionId: %s|tgtQuestionId: %s|srcParentObjId: %s|tgtParentObjId: %s)",
872 $imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename,
873 $question_id, $this->id, $objectId, $this->obj_id
874 ));
875 }
876 }
877 }
878 }
879 }
880
881 function copyImages($question_id, $source_questionpool)
882 {
883 global $ilLog;
884 $imagepath = $this->getImagePath();
885 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
886 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
887 foreach ($this->answers as $answer)
888 {
889 $filename = $answer->getImage();
890 if (strlen($filename))
891 {
892 if (!file_exists($imagepath))
893 {
894 ilUtil::makeDirParents($imagepath);
895 }
896 if (!@copy($imagepath_original . $filename, $imagepath . $filename))
897 {
898 $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
899 $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
900 }
901 if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
902 {
903 if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
904 {
905 $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
906 $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
907 }
908 }
909 }
910 }
911 }
912
916 protected function syncImages()
917 {
918 global $ilLog;
919
920 $imagepath = $this->getImagePath();
921
922 $question_id = $this->getOriginalId();
923 $originalObjId = parent::lookupParentObjId($this->getOriginalId());
924 $imagepath_original = $this->getImagePath($question_id, $originalObjId);
925
926 ilUtil::delDir($imagepath_original);
927 foreach ($this->answers as $answer)
928 {
929 $filename = $answer->getImage();
930 if (strlen($filename))
931 {
932 if (@file_exists($imagepath . $filename))
933 {
934 if (!file_exists($imagepath))
935 {
936 ilUtil::makeDirParents($imagepath);
937 }
938 if (!file_exists($imagepath_original))
939 {
940 ilUtil::makeDirParents($imagepath_original);
941 }
942 if (!@copy($imagepath . $filename, $imagepath_original . $filename))
943 {
944 $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
945 $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
946 }
947 }
948 if (@file_exists($imagepath . $this->getThumbPrefix() . $filename))
949 {
950 if (!@copy($imagepath . $this->getThumbPrefix() . $filename, $imagepath_original . $this->getThumbPrefix() . $filename))
951 {
952 $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
953 $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
954 }
955 }
956 }
957 }
958 }
959
964 {
965 $text = parent::getRTETextWithMediaObjects();
966 foreach ($this->answers as $index => $answer)
967 {
968 $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), $index);
969 $answer_obj = $this->answers[$index];
970 $text .= $answer_obj->getAnswertext();
971 }
972 return $text;
973 }
974
978 function &getAnswers()
979 {
980 return $this->answers;
981 }
982
995 public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
996 {
997 include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
998 $solution = $this->getSolutionValues($active_id, $pass);
999 $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
1000 $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
1001 $i = 1;
1002 foreach ($this->getAnswers() as $id => $answer)
1003 {
1004 $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($answer->getAnswertext()), $format_bold);
1005 $checked = FALSE;
1006 foreach ($solution as $solutionvalue)
1007 {
1008 if ($id == $solutionvalue["value1"])
1009 {
1010 $checked = TRUE;
1011 }
1012 }
1013 if ($checked)
1014 {
1015 $worksheet->write($startrow + $i, 1, 1);
1016 }
1017 else
1018 {
1019 $worksheet->write($startrow + $i, 1, 0);
1020 }
1021 $i++;
1022 }
1023 return $startrow + $i + 1;
1024 }
1025
1026 public function getThumbSize()
1027 {
1028 return $this->thumb_size;
1029 }
1030
1031 public function setThumbSize($a_size)
1032 {
1033 $this->thumb_size = $a_size;
1034 }
1035
1040 {
1041 foreach($this->getAnswers() as $answer)
1042 {
1043 /* @var ASS_AnswerBinaryStateImage $answer */
1044 $answer->setAnswertext( $migrator->migrateToLmContent($answer->getAnswertext()) );
1045 }
1046 }
1047
1051 public function toJSON()
1052 {
1053 require_once './Services/RTE/classes/class.ilRTE.php';
1054 $result = array();
1055 $result['id'] = (int) $this->getId();
1056 $result['type'] = (string) $this->getQuestionType();
1057 $result['title'] = (string) $this->getTitle();
1058 $result['question'] = $this->formatSAQuestion($this->getQuestion());
1059 $result['nr_of_tries'] = (int) $this->getNrOfTries();
1060 $result['shuffle'] = (bool) $this->getShuffle();
1061 $result['feedback'] = array(
1062 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1063 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1064 );
1065
1066 $answers = array();
1067 $has_image = false;
1068 foreach ($this->getAnswers() as $key => $answer_obj)
1069 {
1070 if((string) $answer_obj->getImage())
1071 {
1072 $has_image = true;
1073 }
1074 array_push($answers, array(
1075 "answertext" => (string) $this->formatSAQuestion($answer_obj->getAnswertext()),
1076 "points_checked" => (float) $answer_obj->getPointsChecked(),
1077 "points_unchecked" => (float) $answer_obj->getPointsUnchecked(),
1078 "order" => (int) $answer_obj->getOrder(),
1079 "image" => (string) $answer_obj->getImage(),
1080 "feedback" => $this->formatSAQuestion(
1081 $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), $key)
1082 )
1083 ));
1084 }
1085 $result['answers'] = $answers;
1086
1087 if($has_image)
1088 {
1089 $result['path'] = $this->getImagePathWeb();
1090 $result['thumb'] = $this->getThumbSize();
1091 }
1092
1093 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1094 $result['mobs'] = $mobs;
1095
1096 return json_encode($result);
1097 }
1098
1099 public function removeAnswerImage($index)
1100 {
1101 $answer = $this->answers[$index];
1102 if (is_object($answer))
1103 {
1104 $this->deleteImage($answer->getImage());
1105 $answer->setImage('');
1106 }
1107 }
1108
1110 {
1111 global $ilUser;
1112
1113 $multilineAnswerSetting = $ilUser->getPref("tst_multiline_answers");
1114 if ($multilineAnswerSetting != 1)
1115 {
1116 $multilineAnswerSetting = 0;
1117 }
1118 return $multilineAnswerSetting;
1119 }
1120
1121 function setMultilineAnswerSetting($a_setting = 0)
1122 {
1123 global $ilUser;
1124 $ilUser->writePref("tst_multiline_answers", $a_setting);
1125 }
1126
1136 function setSpecificFeedbackSetting($a_feedback_setting)
1137 {
1138 $this->feedback_setting = $a_feedback_setting;
1139 }
1140
1151 {
1152 if ($this->feedback_setting)
1153 {
1155 }
1156 else
1157 {
1158 return 1;
1159 }
1160 }
1161
1163 {
1164 return 'feedback_correct_sc_mc';
1165 }
1166
1178 public function isAnswered($active_id, $pass = NULL)
1179 {
1180 $numExistingSolutionRecords = assQuestion::getNumExistingSolutionRecords($active_id, $pass, $this->getId());
1181
1182 return $numExistingSolutionRecords > 0;
1183 }
1184
1196 public static function isObligationPossible($questionId)
1197 {
1199 global $ilDB;
1200
1201 $query = "
1202 SELECT SUM(points) points_for_checked_answers
1203 FROM qpl_a_mc
1204 WHERE question_fi = %s AND points > 0
1205 ";
1206
1207 $res = $ilDB->queryF($query, array('integer'), array($questionId));
1208
1209 $row = $ilDB->fetchAssoc($res);
1210
1211 return $row['points_for_checked_answers'] > 0;
1212 }
1213
1222 public function ensureNoInvalidObligation($questionId)
1223 {
1225 global $ilDB;
1226
1227 $query = "
1228 SELECT SUM(qpl_a_mc.points) points_for_checked_answers,
1229 test_question_id
1230
1231 FROM tst_test_question
1232
1233 INNER JOIN qpl_a_mc
1234 ON qpl_a_mc.question_fi = tst_test_question.question_fi
1235
1236 WHERE tst_test_question.question_fi = %s
1237 AND tst_test_question.obligatory = 1
1238
1239 GROUP BY test_question_id
1240 ";
1241
1242 $res = $ilDB->queryF($query, array('integer'), array($questionId));
1243
1244 $updateTestQuestionIds = array();
1245
1246 while( $row = $ilDB->fetchAssoc($res) )
1247 {
1248 if( $row['points_for_checked_answers'] <= 0 )
1249 {
1250 $updateTestQuestionIds[] = $row['test_question_id'];
1251 }
1252 }
1253
1254 if( count($updateTestQuestionIds) )
1255 {
1256 $test_question_id__IN__updateTestQuestionIds = $ilDB->in(
1257 'test_question_id', $updateTestQuestionIds, false, 'integer'
1258 );
1259
1260 $query = "
1261 UPDATE tst_test_question
1262 SET obligatory = 0
1263 WHERE $test_question_id__IN__updateTestQuestionIds
1264 ";
1265
1266 $ilDB->manipulate($query);
1267 }
1268 }
1269
1273 protected function getSolutionSubmit()
1274 {
1275 $solutionSubmit = array();
1276 foreach($_POST as $key => $value)
1277 {
1278 if(preg_match("/^multiple_choice_result_(\d+)/", $key))
1279 {
1280 if(strlen($value))
1281 {
1282 $solutionSubmit[] = $value;
1283 }
1284 }
1285 }
1286 return $solutionSubmit;
1287 }
1288
1294 protected function calculateReachedPointsForSolution($found_values, $active_id = 0)
1295 {
1296 $points = 0;
1297 foreach($this->answers as $key => $answer)
1298 {
1299 if(in_array($key, $found_values))
1300 {
1301 $points += $answer->getPoints();
1302 } else
1303 {
1304 $points += $answer->getPointsUnchecked();
1305 }
1306 }
1307 if($active_id)
1308 {
1309 include_once "./Modules/Test/classes/class.ilObjTest.php";
1310 $mc_scoring = ilObjTest::_getMCScoring($active_id);
1311 if(($mc_scoring == 0) && (count($found_values) == 0))
1312 {
1313 $points = 0;
1314 }
1315 }
1316 return $points;
1317 }
1318
1327 public function getOperators($expression)
1328 {
1329 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1331 }
1332
1337 public function getExpressionTypes()
1338 {
1339 return array(
1344 );
1345 }
1346
1355 public function getUserQuestionResult($active_id, $pass)
1356 {
1358 global $ilDB;
1359 $result = new ilUserQuestionResult($this, $active_id, $pass);
1360
1361 $maxStep = $this->lookupMaxStep($active_id, $pass);
1362
1363 if( $maxStep !== null )
1364 {
1365 $data = $ilDB->queryF(
1366 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1367 array("integer", "integer", "integer","integer"),
1368 array($active_id, $pass, $this->getId(), $maxStep)
1369 );
1370 }
1371 else
1372 {
1373 $data = $ilDB->queryF(
1374 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1375 array("integer", "integer", "integer"),
1376 array($active_id, $pass, $this->getId())
1377 );
1378 }
1379
1380 while($row = $ilDB->fetchAssoc($data))
1381 {
1382 $result->addKeyValue($row["value1"], $row["value1"]);
1383 }
1384
1385 $points = $this->calculateReachedPoints($active_id, $pass);
1386 $max_points = $this->getMaximumPoints();
1387
1388 $result->setReachedPercentage(($points/$max_points) * 100);
1389
1390 return $result;
1391 }
1392
1401 public function getAvailableAnswerOptions($index = null)
1402 {
1403 if($index !== null)
1404 {
1405 return $this->getAnswer($index);
1406 }
1407 else
1408 {
1409 return $this->getAnswers();
1410 }
1411 }
1412}
$result
print $file
$filename
Definition: buildRTE.php:89
ASS_AnswerBinaryStateImage is a class for answers with a binary state indicator (checked/unchecked,...
Class for multiple choice tests.
syncImages()
Sync images of a MC question on synchronisation with the original question.
toJSON()
Returns a JSON representation of the question.
getSpecificFeedbackSetting()
Gets the current feedback settings in effect for the question.
copyImages($question_id, $source_questionpool)
saveToDb($original_id="")
Saves a assMultipleChoice object to a database.
loadFromDb($question_id)
Loads a assMultipleChoice object from a database.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assMultipleChoiceQuestion.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
getAnswerCount()
Returns the number of answers.
getAnswerTableName()
Returns the name of the answer table in the database.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
isAnswered($active_id, $pass=NULL)
returns boolean wether the question is answered during test pass or not
getAdditionalTableName()
Returns the name of the additional question data table in the database.
addAnswer( $answertext="", $points=0.0, $points_unchecked=0.0, $order=0, $answerimage="")
Adds a possible answer for a multiple choice question.
setSpecificFeedbackSetting($a_feedback_setting)
Sets the feedback settings in effect for the question.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
calculateReachedPointsForSolution($found_values, $active_id=0)
getOutputType()
Gets the multiple choice output type which is either OUTPUT_ORDER (=0) or OUTPUT_RANDOM (=1).
copyObject($target_questionpool_id, $title="")
Copies an assMultipleChoice object.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
setMultilineAnswerSetting($a_setting=0)
isComplete()
Returns true, if a multiple choice question is complete for use.
flushAnswers()
Deletes all answers.
deleteAnswer($index=0)
Deletes an answer with a given index.
getQuestionType()
Returns the question type of the question.
deleteImage($image_filename)
Deletes an image file.
setImageFile($image_filename, $image_tempfilename="")
Sets the image file and uploads the image to the object's image directory.
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $output_type=OUTPUT_ORDER)
assMultipleChoice constructor
setIsSingleline($isSingleline)
setOutputType($output_type=OUTPUT_ORDER)
Sets the output type of the assMultipleChoice object.
getAnswer($index=0)
Returns an answer with a given index.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
generateThumbForFile($path, $file)
getExpressionTypes()
Get all available expression types for a specific question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
rebuildThumbnails()
Rebuild the thumbnail images with a new thumbnail size.
& getAnswers()
Returns a reference to the answers array.
getOperators($expression)
Get all available operations for a specific question.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
setShuffle($shuffle=true)
Sets the shuffle flag.
setId($id=-1)
Sets the id of the assQuestion object.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
setAuthor($author="")
Sets the authors name of the assQuestion object.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
getShuffle()
Gets the shuffle flag.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true, $ignoredSolutionIds=array())
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
setNrOfTries($a_nr_of_tries)
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
setQuestion($question="")
Sets the question string of the question object.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
_convert_text($a_text, $a_target="has been removed")
_getLogLanguage()
retrieve the log language for assessment logging
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
static getMimeType($a_file, $a_external=false)
get mime type for file
_getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
_getMCScoring($active_id)
Gets the scoring type for multiple choice questions.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static convertImage($a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
static makeDirParents($a_dir)
Create a new directory and all parent directories.
$_POST['username']
Definition: cron.php:12
$data
$text
const OUTPUT_ORDER
Class iQuestionCondition.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
Interface ilObjAnswerScoringAdjustable.
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
Interface ilObjQuestionScoringAdjustable.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
$path
Definition: index.php:22
global $ilDB
$mobs
global $ilUser
Definition: imgupload.php:15