ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.assTextQuestion.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';
8
23{
32
37
46 public $keywords;
47
48 public $answers;
49
56
57 /* method for automatic string matching */
59
60 public $keyword_relation = 'any';
61
74 public function __construct(
75 $title = "",
76 $comment = "",
77 $author = "",
78 $owner = -1,
79 $question = ""
80 ) {
82 $this->wordCounterEnabled = false;
83 $this->maxNumOfChars = 0;
84 $this->points = 1;
85 $this->answers = array();
86 $this->matchcondition = 0;
87 }
88
94 public function isComplete()
95 {
96 if (strlen($this->title)
97 && $this->author
98 && $this->question
99 && $this->getMaximumPoints() > 0
100 ) {
101 return true;
102 }
103 return false;
104 }
105
111 public function saveToDb($original_id = "")
112 {
116 parent::saveToDb($original_id);
117 }
118
126 public function loadFromDb($question_id)
127 {
128 global $DIC;
129 $ilDB = $DIC['ilDB'];
130
131 $result = $ilDB->queryF(
132 "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",
133 array("integer"),
134 array($question_id)
135 );
136 if ($ilDB->numRows($result) == 1) {
137 $data = $ilDB->fetchAssoc($result);
138 $this->setId($question_id);
139 $this->setObjId($data["obj_fi"]);
140 $this->setTitle($data["title"]);
141 $this->setComment($data["description"]);
142 $this->setOriginalId($data["original_id"]);
143 $this->setNrOfTries($data['nr_of_tries']);
144 $this->setAuthor($data["author"]);
145 $this->setPoints((float) $data["points"]);
146 $this->setOwner($data["owner"]);
147 include_once("./Services/RTE/classes/class.ilRTE.php");
148 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
149 $this->setShuffle($data["shuffle"]);
150 $this->setWordCounterEnabled((bool) $data['word_cnt_enabled']);
151 $this->setMaxNumOfChars($data["maxnumofchars"]);
152 $this->setTextRating($this->isValidTextRating($data["textgap_rating"]) ? $data["textgap_rating"] : TEXTGAP_RATING_CASEINSENSITIVE);
153 $this->matchcondition = (strlen($data['matchcondition'])) ? $data['matchcondition'] : 0;
154 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
155 $this->setKeywordRelation(($data['keyword_relation']));
156
157 try {
158 $this->setLifecycle(ilAssQuestionLifecycle::getInstance($data['lifecycle']));
161 }
162
163 try {
164 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
166 }
167 }
168
169 $result = $ilDB->queryF(
170 "SELECT * FROM qpl_a_essay WHERE question_fi = %s",
171 array("integer"),
172 array($this->getId())
173 );
174
175 $this->flushAnswers();
176 while ($row = $ilDB->fetchAssoc($result)) {
177 $this->addAnswer($row['answertext'], $row['points']);
178 }
179
180 parent::loadFromDb($question_id);
181 }
182
188 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
189 {
190 if ($this->id <= 0) {
191 // The question has not been saved. It cannot be duplicated
192 return;
193 }
194 // duplicate the question in database
195 $this_id = $this->getId();
196 $thisObjId = $this->getObjId();
197
198 $clone = $this;
199 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
201 $clone->id = -1;
202
203 if ((int) $testObjId > 0) {
204 $clone->setObjId($testObjId);
205 }
206
207 if ($title) {
208 $clone->setTitle($title);
209 }
210
211 if ($author) {
212 $clone->setAuthor($author);
213 }
214 if ($owner) {
215 $clone->setOwner($owner);
216 }
217
218 if ($for_test) {
219 $clone->saveToDb($original_id);
220 } else {
221 $clone->saveToDb();
222 }
223
224 // copy question page content
225 $clone->copyPageOfQuestion($this_id);
226 // copy XHTML media objects
227 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
228 #$clone->duplicateAnswers($this_id);
229
230 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
231
232 return $clone->id;
233 }
234
240 public function copyObject($target_questionpool_id, $title = "")
241 {
242 if ($this->id <= 0) {
243 // The question has not been saved. It cannot be duplicated
244 return;
245 }
246 // duplicate the question in database
247 $clone = $this;
248 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
250 $clone->id = -1;
251 $source_questionpool_id = $this->getObjId();
252 $clone->setObjId($target_questionpool_id);
253 if ($title) {
254 $clone->setTitle($title);
255 }
256 $clone->saveToDb();
257 // copy question page content
258 $clone->copyPageOfQuestion($original_id);
259 // copy XHTML media objects
260 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
261 // duplicate answers
262 #$clone->duplicateAnswers($original_id);
263
264 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
265
266 return $clone->id;
267 }
268
269 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
270 {
271 if ($this->id <= 0) {
272 // The question has not been saved. It cannot be duplicated
273 return;
274 }
275
276 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
277
278 $sourceQuestionId = $this->id;
279 $sourceParentId = $this->getObjId();
280
281 // duplicate the question in database
282 $clone = $this;
283 $clone->id = -1;
284
285 $clone->setObjId($targetParentId);
286
287 if ($targetQuestionTitle) {
288 $clone->setTitle($targetQuestionTitle);
289 }
290
291 $clone->saveToDb();
292 // copy question page content
293 $clone->copyPageOfQuestion($sourceQuestionId);
294 // copy XHTML media objects
295 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
296 // duplicate answers
297 #$clone->duplicateAnswers($sourceQuestionId);
298
299 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
300
301 return $clone->id;
302 }
303
311 public function getMaxNumOfChars()
312 {
313 if (strcmp($this->maxNumOfChars, "") == 0) {
314 return 0;
315 } else {
317 }
318 }
319
327 public function setMaxNumOfChars($maxchars = 0)
328 {
329 $this->maxNumOfChars = $maxchars;
330 }
331
335 public function isWordCounterEnabled()
336 {
338 }
339
344 {
345 $this->wordCounterEnabled = $wordCounterEnabled;
346 }
347
354 public function getMaximumPoints()
355 {
356 if (in_array($this->getKeywordRelation(), self::getScoringModesWithPointsByQuestion())) {
357 return parent::getPoints();
358 }
359
360 $points = 0;
361
362 foreach ($this->answers as $answer) {
363 if ($answer->getPoints() > 0) {
364 $points = $points + $answer->getPoints();
365 }
366 }
367
368 return $points;
369 }
370
371 public function getMinimumPoints()
372 {
373 if (in_array($this->getKeywordRelation(), self::getScoringModesWithPointsByQuestion())) {
374 return 0;
375 }
376
377 $points = 0;
378
379 foreach ($this->answers as $answer) {
380 if ($answer->getPoints() < 0) {
381 $points = $points + $answer->getPoints();
382 }
383 }
384
385 return $points;
386 }
396 public function setReachedPoints($active_id, $points, $pass = null)
397 {
398 global $DIC;
399 $ilDB = $DIC['ilDB'];
400
401 if (($points > 0) && ($points <= $this->getPoints())) {
402 if (is_null($pass)) {
403 $pass = $this->getSolutionMaxPass($active_id);
404 }
405 $affectedRows = $ilDB->manipulateF(
406 "UPDATE tst_test_result SET points = %s WHERE active_fi = %s AND question_fi = %s AND pass = %s",
407 array('float','integer','integer','integer'),
408 array($points, $active_id, $this->getId(), $pass)
409 );
410 self::_updateTestPassResults($active_id, $pass);
411 return true;
412 } else {
413 return true;
414 }
415 }
416
417 private function isValidTextRating($textRating)
418 {
419 switch ($textRating) {
427 return true;
428 }
429
430 return false;
431 }
432
441 public function isKeywordMatching($answertext, $a_keyword)
442 {
443 $result = false;
444 $textrating = $this->getTextRating();
445 include_once "./Services/Utilities/classes/class.ilStr.php";
446 switch ($textrating) {
448 if (ilStr::strPos(ilStr::strToLower($answertext), ilStr::strToLower($a_keyword)) !== false) {
449 return true;
450 }
451 break;
453 if (ilStr::strPos($answertext, $a_keyword) !== false) {
454 return true;
455 }
456 break;
457 }
458
459 // "<p>red</p>" would not match "red" even with distance of 5
460 $answertext = strip_tags($answertext);
461
462 $answerwords = array();
463 if (preg_match_all("/([^\s.]+)/", $answertext, $matches)) {
464 foreach ($matches[1] as $answerword) {
465 array_push($answerwords, trim($answerword));
466 }
467 }
468 foreach ($answerwords as $a_original) {
469 switch ($textrating) {
471 if (levenshtein($a_original, $a_keyword) <= 1) {
472 return true;
473 }
474 break;
476 if (levenshtein($a_original, $a_keyword) <= 2) {
477 return true;
478 }
479 break;
481 if (levenshtein($a_original, $a_keyword) <= 3) {
482 return true;
483 }
484 break;
486 if (levenshtein($a_original, $a_keyword) <= 4) {
487 return true;
488 }
489 break;
491 if (levenshtein($a_original, $a_keyword) <= 5) {
492 return true;
493 }
494 break;
495 }
496 }
497 return $result;
498 }
499
500 protected function calculateReachedPointsForSolution($solution)
501 {
502 // Return min points when keyword relation is NON KEYWORDS
503 if ($this->getKeywordRelation() == 'non') {
504 return $this->getMinimumPoints();
505 }
506
507 // Return min points if there are no answers present.
508 $answers = $this->getAnswers();
509
510 if (count($answers) == 0) {
511 return $this->getMinimumPoints();
512 }
513
514 switch ($this->getKeywordRelation()) {
515 case 'any':
516
517 $points = 0;
518
519 foreach ($answers as $answer) {
520 $qst_answer = $answer->getAnswertext();
521 $user_answer = ' ' . $solution;
522
523 if ($this->isKeywordMatching($user_answer, $qst_answer)) {
524 $points += $answer->getPoints();
525 }
526 }
527
528 break;
529
530 case 'all':
531
532 $points = $this->getMaximumPoints();
533
534 foreach ($answers as $answer) {
535 $qst_answer = $answer->getAnswertext();
536 $user_answer = ' ' . $solution;
537
538 if (!$this->isKeywordMatching($user_answer, $qst_answer)) {
539 $points = 0;
540 break;
541 }
542 }
543
544 break;
545
546 case 'one':
547
548 $points = 0;
549
550 foreach ($answers as $answer) {
551 $qst_answer = $answer->getAnswertext();
552 $user_answer = ' ' . $solution;
553
554 if ($this->isKeywordMatching($user_answer, $qst_answer)) {
555 $points = $this->getMaximumPoints();
556 break;
557 }
558 }
559
560 break;
561 }
562
563 return $points;
564 }
565
576 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
577 {
578 if ($returndetails) {
579 throw new ilTestException('return details not implemented for ' . __METHOD__);
580 }
581
582 global $DIC;
583 $ilDB = $DIC['ilDB'];
584
585 $points = 0;
586 if (is_null($pass)) {
587 $pass = $this->getSolutionMaxPass($active_id);
588 }
589
590 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
591
592 // Return min points when no answer was given.
593 if ($ilDB->numRows($result) == 0) {
594 return $this->getMinimumPoints();
595 }
596
597 // Return points of points are already on the row.
598 $row = $ilDB->fetchAssoc($result);
599 if ($row["points"] != null) {
600 return $row["points"];
601 }
602
603 return $this->calculateReachedPointsForSolution($row['value1']);
604 }
605
614 public function saveWorkingData($active_id, $pass = null, $authorized = true)
615 {
616 global $DIC;
617 $ilDB = $DIC['ilDB'];
618 $ilUser = $DIC['ilUser'];
619
620 include_once "./Services/Utilities/classes/class.ilStr.php";
621 if (is_null($pass)) {
622 include_once "./Modules/Test/classes/class.ilObjTest.php";
623 $pass = ilObjTest::_getPass($active_id);
624 }
625
626 $entered_values = 0;
627 $text = $this->getSolutionSubmit();
628
629 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized, $text) {
630 $this->removeCurrentSolution($active_id, $pass, $authorized);
631
632 if (strlen($text)) {
633 $this->saveCurrentSolution($active_id, $pass, trim($text), null, $authorized);
634 $entered_values++;
635 }
636 });
637
638 if ($entered_values) {
639 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
641 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
642 }
643 } else {
644 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
646 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
647 }
648 }
649
650 return true;
651 }
652
656 public function getSolutionSubmit()
657 {
658 $text = ilUtil::stripSlashes($_POST["TEXT"], false);
659
660 if (ilUtil::isHTML($text)) {
661 $text = $this->getHtmlUserSolutionPurifier()->purify($text);
662 }
663
664 return $text;
665 }
666
667 public function saveAdditionalQuestionDataToDb()
668 {
670 global $DIC;
671 $ilDB = $DIC['ilDB'];
672 $ilDB->manipulateF(
673 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
674 array( "integer" ),
675 array( $this->getId()
676 )
677 );
678
679 $fields = array(
680 'question_fi' => array('integer', $this->getId()),
681 'maxnumofchars' => array('integer', $this->getMaxNumOfChars()),
682 'word_cnt_enabled' => array('integer', (int) $this->isWordCounterEnabled()),
683 'keywords' => array('text', null),
684 'textgap_rating' => array('text', $this->getTextRating()),
685 'matchcondition' => array('integer', $this->matchcondition),
686 'keyword_relation' => array('text', $this->getKeywordRelation())
687 );
688
689 $ilDB->insert($this->getAdditionalTableName(), $fields);
690 }
691
692 public function saveAnswerSpecificDataToDb()
693 {
695 global $DIC;
696 $ilDB = $DIC['ilDB'];
697
698 $ilDB->manipulateF(
699 "DELETE FROM qpl_a_essay WHERE question_fi = %s",
700 array( "integer" ),
701 array( $this->getId() )
702 );
703
704 foreach ($this->answers as $answer) {
706 $nextID = $ilDB->nextId('qpl_a_essay');
707 $ilDB->manipulateF(
708 "INSERT INTO qpl_a_essay (answer_id, question_fi, answertext, points) VALUES (%s, %s, %s, %s)",
709 array( "integer", "integer", "text", 'float' ),
710 array(
711 $nextID,
712 $this->getId(),
713 $answer->getAnswertext(),
714 $answer->getPoints()
715 )
716 );
717 }
718 }
719
726 public function getQuestionType()
727 {
728 return "assTextQuestion";
729 }
730
738 public function getTextRating()
739 {
740 return $this->text_rating;
741 }
742
750 public function setTextRating($a_text_rating)
751 {
752 switch ($a_text_rating) {
760 $this->text_rating = $a_text_rating;
761 break;
762 default:
763 $this->text_rating = TEXTGAP_RATING_CASEINSENSITIVE;
764 break;
765 }
766 }
767
774 public function getAdditionalTableName()
775 {
776 return "qpl_qst_essay";
777 }
778
784 {
785 return parent::getRTETextWithMediaObjects();
786 }
787
791 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
792 {
793 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
794
795 $solutions = $this->getSolutionValues($active_id, $pass);
796
797 $i = 1;
798 $worksheet->setCell($startrow + $i, 0, $this->lng->txt("result"));
799 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
800
801 require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
802 $assessment_folder = new ilObjAssessmentFolder();
803
804 $string_escaping_org_value = $worksheet->getStringEscaping();
805 if ($assessment_folder->getExportEssayQuestionsWithHtml() == 1) {
806 $worksheet->setStringEscaping(false);
807 }
808
809 if (strlen($solutions[0]["value1"])) {
810 $worksheet->setCell($startrow + $i, 1, $solutions[0]["value1"]);
811 }
812 $i++;
813
814 $worksheet->setStringEscaping($string_escaping_org_value);
815 return $startrow + $i + 1;
816 }
817
821 public function toJSON()
822 {
823 include_once("./Services/RTE/classes/class.ilRTE.php");
824 $result = array();
825 $result['id'] = (int) $this->getId();
826 $result['type'] = (string) $this->getQuestionType();
827 $result['title'] = (string) $this->getTitle();
828 $result['question'] = $this->formatSAQuestion($this->getQuestion());
829 $result['nr_of_tries'] = (int) $this->getNrOfTries();
830 $result['shuffle'] = (bool) $this->getShuffle();
831 $result['maxlength'] = (int) $this->getMaxNumOfChars();
832 return json_encode($result);
833 }
834
835 public function getAnswerCount()
836 {
837 return count($this->answers);
838 }
839
853 public function addAnswer(
854 $answertext = "",
855 $points = 0.0,
856 $points_unchecked = 0.0,
857 $order = 0,
858 $answerimage = ""
859 ) {
860 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
861
862 // add answer
863 $answer = new ASS_AnswerMultipleResponseImage($answertext, $points);
864 $this->answers[] = $answer;
865 }
866
867 public function getAnswers()
868 {
869 return $this->answers;
870 }
871
881 public function getAnswer($index = 0)
882 {
883 if ($index < 0) {
884 return null;
885 }
886 if (count($this->answers) < 1) {
887 return null;
888 }
889 if ($index >= count($this->answers)) {
890 return null;
891 }
892
893 return $this->answers[$index];
894 }
895
904 public function deleteAnswer($index = 0)
905 {
906 if ($index < 0) {
907 return;
908 }
909 if (count($this->answers) < 1) {
910 return;
911 }
912 if ($index >= count($this->answers)) {
913 return;
914 }
915 $answer = $this->answers[$index];
916 if (strlen($answer->getImage())) {
917 $this->deleteImage($answer->getImage());
918 }
919 unset($this->answers[$index]);
920 $this->answers = array_values($this->answers);
921 for ($i = 0; $i < count($this->answers); $i++) {
922 if ($this->answers[$i]->getOrder() > $index) {
923 $this->answers[$i]->setOrder($i);
924 }
925 }
926 }
927
928 public function getAnswerTableName()
929 {
930 return 'qpl_a_essay';
931 }
932
939 public function flushAnswers()
940 {
941 $this->answers = array();
942 }
943
944 public function setAnswers($answers)
945 {
946 if (isset($answers['answer'])) {
947 $count = count($answers['answer']);
948 $withPoints = true;
949 } else {
950 $count = count($answers);
951 $withPoints = false;
952 }
953
954 $this->flushAnswers();
955
956 for ($i = 0; $i < $count; $i++) {
957 if ($withPoints) {
958 $this->addAnswer($answers['answer'][$i], $answers['points'][$i]);
959 } else {
960 $this->addAnswer($answers[$i], 0);
961 }
962 }
963 }
964
966 {
967 global $DIC;
968 $ilDB = $DIC['ilDB'];
969
970 $result = $ilDB->queryF(
971 "SELECT * FROM qpl_a_essay WHERE question_fi = %s",
972 array('integer'),
973 array($original_id)
974 );
975 if ($result->numRows()) {
976 while ($row = $ilDB->fetchAssoc($result)) {
977 $next_id = $ilDB->nextId('qpl_a_essay');
978 $affectedRows = $ilDB->manipulateF(
979 "INSERT INTO qpl_a_essay (answer_id, question_fi, answertext, points)
980 VALUES (%s, %s, %s, %s)",
981 array('integer','integer','text','float'),
982 array($next_id, $this->getId(), $row["answertext"], $row["points"])
983 );
984 }
985 }
986 }
987
988 public function getKeywordRelation()
989 {
991 }
992
997 public function setKeywordRelation($a_relation)
998 {
999 $this->keyword_relation = $a_relation;
1000 }
1001
1002 public static function getValidScoringModes()
1003 {
1004 return array_merge(self::getScoringModesWithPointsByQuestion(), self::getScoringModesWithPointsByKeyword());
1005 }
1006
1008 {
1009 return array('non', 'all', 'one');
1010 }
1011
1012 public static function getScoringModesWithPointsByKeyword()
1013 {
1014 return array('any');
1015 }
1016
1017
1028 public function isAnswered($active_id, $pass = null)
1029 {
1030 $numExistingSolutionRecords = assQuestion::getNumExistingSolutionRecords($active_id, $pass, $this->getId());
1031
1032 return $numExistingSolutionRecords > 0;
1033 }
1034
1045 public static function isObligationPossible($questionId)
1046 {
1047 return true;
1048 }
1049
1050 public function countLetters($text)
1051 {
1052 $text = strip_tags($text);
1053
1054 $text = str_replace('&gt;', '>', $text);
1055 $text = str_replace('&lt;', '<', $text);
1056 $text = str_replace('&nbsp;', ' ', $text);
1057 $text = str_replace('&amp;', '&', $text);
1058
1059 $text = str_replace("\r\n", "\n", $text);
1060 $text = str_replace("\n", "", $text);
1061
1062 return ilStr::strLen($text);
1063 }
1064
1065 public function countWords($text)
1066 {
1067 $text = str_replace('&nbsp;', ' ', $text);
1068
1069 $text = preg_replace('/[.,:;!?\-_#\'"+*\\/=()&%§$]/m', '', $text);
1070
1071 $text = preg_replace('/^\s*/m', '', $text);
1072 $text = preg_replace('/\s*$/m', '', $text);
1073 $text = preg_replace('/\s+/m', ' ', $text);
1074
1075 return count(explode(' ', $text));
1076 }
1077
1078 public function getLatestAutosaveContent($active_id)
1079 {
1080 $question_fi = $this->getId();
1081
1082 // Do we have an unauthorized result?
1083 $cntresult = $this->db->query('
1084 SELECT count(solution_id) cnt
1085 FROM tst_solutions
1086 WHERE active_fi = ' . $this->db->quote($active_id, 'int') . '
1087 AND question_fi = ' . $this->db->quote($this->getId(), 'int') . '
1088 AND authorized = ' . $this->db->quote(0, 'int')
1089 );
1090 $row = $this->db->fetchAssoc($cntresult);
1091 if($row['cnt'] > 0 ) {
1092 $tresult = $this->db->query('
1093 SELECT value1
1094 FROM tst_solutions
1095 WHERE active_fi = ' . $this->db->quote($active_id, 'int') . '
1096 AND question_fi = ' . $this->db->quote($this->getId(), 'int') . '
1097 AND authorized = ' . $this->db->quote(0, 'int')
1098 );
1099 $trow = $this->db->fetchAssoc($tresult);
1100 return $trow['value1'];
1101 }
1102 return '';
1103 }
1104}
$result
$_POST["username"]
ASS_AnswerBinaryStateImage is a class for answers with a binary state indicator (checked/unchecked,...
An exception for terminatinating execution or to throw for unit testing.
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.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
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.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
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.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true)
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.
getPoints()
Returns the maximum available points for the question.
getShuffle()
Gets the shuffle flag.
setLifecycle(ilAssQuestionLifecycle $lifecycle)
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
setQuestion($question="")
Sets the question string of the question object.
Class for text questions.
setMaxNumOfChars($maxchars=0)
Sets the maximum number of characters for the text solution.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
isAnswered($active_id, $pass=null)
returns boolean wether the question is answered during test pass or not
isKeywordMatching($answertext, $a_keyword)
Checks if one of the keywords matches the answertext.
saveToDb($original_id="")
Saves a assTextQuestion object to a database.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
loadFromDb($question_id)
Loads a assTextQuestion object from a database.
addAnswer( $answertext="", $points=0.0, $points_unchecked=0.0, $order=0, $answerimage="")
Adds a possible answer for a multiple choice question.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
isComplete()
Returns true, if a multiple choice question is complete for use.
setKeywordRelation($a_relation)
This method implements a default behaviour.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
getAnswer($index=0)
Returns an answer with a given index.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
static getScoringModesWithPointsByKeyword()
setWordCounterEnabled($wordCounterEnabled)
toJSON()
Returns a JSON representation of the question.
getAnswerTableName()
Returns the name of the answer table in the database.
flushAnswers()
Deletes all answers.
setTextRating($a_text_rating)
Sets the rating option for text comparisons.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assTextQuestion.
copyObject($target_questionpool_id, $title="")
Copies an assTextQuestion object.
getQuestionType()
Returns the question type of the question.
deleteAnswer($index=0)
Deletes an answer with a given index.
getMaxNumOfChars()
Gets the maximum number of characters for the text solution.
calculateReachedPointsForSolution($solution)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
isValidTextRating($textRating)
getLatestAutosaveContent($active_id)
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
setReachedPoints($active_id, $points, $pass=null)
Sets the points, a learner has reached answering the question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assTextQuestion constructor
static getScoringModesWithPointsByQuestion()
getTextRating()
Returns the rating option for text comparisons.
duplicateAnswers($original_id)
Class ilObjAssessmentFolder.
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
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...
static strPos($a_haystack, $a_needle, $a_offset=null)
Definition: class.ilStr.php:30
static strToLower($a_string)
Definition: class.ilStr.php:87
static strLen($a_string)
Definition: class.ilStr.php:78
Base Exception for all Exceptions relating to Modules/Test.
static isHTML($a_text)
Checks if a given string contains HTML or not.
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
const TEXTGAP_RATING_LEVENSHTEIN5
const TEXTGAP_RATING_LEVENSHTEIN4
const TEXTGAP_RATING_LEVENSHTEIN3
const TEXTGAP_RATING_CASESENSITIVE
const TEXTGAP_RATING_LEVENSHTEIN2
const TEXTGAP_RATING_CASEINSENSITIVE
const TEXTGAP_RATING_LEVENSHTEIN1
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.
$index
Definition: metadata.php:128
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $ilDB
$data
Definition: storeScorm.php:23
$ilUser
Definition: imgupload.php:18
$DIC
Definition: xapitoken.php:46