ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.assLongMenu.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.iQuestionCondition.php';
8require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
9
10
12{
13 private $answerType;
16 private $ilDB;
20
23 const GAP_PLACEHOLDER = 'Longmenu';
25 const MAX_INPUT_FIELDS = 500;
26
28 private $correct_answers = [];
29
31 private $answers = [];
32
33 public function __construct(
34 $title = "",
35 $comment = "",
36 $author = "",
37 $owner = -1,
38 $question = ""
39 ) {
40 global $DIC;
41 require_once 'Modules/TestQuestionPool/classes/feedback/class.ilAssConfigurableMultiOptionQuestionFeedback.php';
43 $this->minAutoComplete = self::MIN_LENGTH_AUTOCOMPLETE;
45 $this->ilDB = $DIC->database();
46 $this->identical_scoring = 1;
47 }
48
52 public function getAnswerType()
53 {
54 return $this->answerType;
55 }
56
60 public function setAnswerType($answerType)
61 {
62 $this->answerType = $answerType;
63 }
64
68 public function getCorrectAnswers()
69 {
71 }
72
73
75 {
76 $this->correct_answers = $correct_answers;
77 }
78
79 private function buildFolderName()
80 {
81 return ilUtil::getDataDir() . '/assessment/longMenuQuestion/' . $this->getId() . '/' ;
82 }
83
84 public function getAnswerTableName()
85 {
86 return "qpl_a_lome";
87 }
88
89 private function buildFileName($gap_id)
90 {
91 try {
92 $this->assertDirExists();
93 return $this->buildFolderName() . $gap_id . '.txt';
94 } catch (ilException $e) {
95 }
96 }
97
99 {
100 $this->long_menu_text = $this->getHtmlQuestionContentPurifier()->purify($long_menu_text);
101 }
102
103 public function getLongMenuTextValue()
104 {
106 }
107
108 public function setAnswers($answers)
109 {
110 $this->answers = $answers;
111 }
112
113 public function getAnswers()
114 {
115 return $this->answers;
116 }
117
121 public function getJsonStructure()
122 {
124 }
125
130 {
131 $this->json_structure = $json_structure;
132 }
133
135 {
136 $this->specificFeedbackSetting = $specificFeedbackSetting;
137 }
138
140 {
142 }
143
145 {
146 $this->minAutoComplete = $minAutoComplete;
147 }
148
149 public function getMinAutoComplete()
150 {
151 return $this->minAutoComplete ? $this->minAutoComplete : self::MIN_LENGTH_AUTOCOMPLETE;
152 }
153
154 public function isComplete()
155 {
156 if (strlen($this->title)
157 && $this->author
158 && $this->long_menu_text
159 && sizeof($this->answers) > 0
160 && sizeof($this->correct_answers) > 0
161 && $this->getPoints() > 0
162 ) {
163 return true;
164 }
165 return false;
166 }
167
168 public function saveToDb($original_id = "")
169 {
173 parent::saveToDb($original_id);
174 }
175
180 public function checkQuestionCustomPart($form = null)
181 {
182 $hidden_text_files = $this->getAnswers();
184 $points = array();
185 if (sizeof($correct_answers) == 0 || sizeof($hidden_text_files) == 0) {
186 return false;
187 }
188 if (sizeof($correct_answers) != sizeof($hidden_text_files)) {
189 return false;
190 }
191 foreach ($correct_answers as $key => $correct_answers_row) {
192 if ($this->correctAnswerDoesNotExistInAnswerOptions($correct_answers_row, $hidden_text_files[$key])) {
193 return false;
194 }
195 if (!is_array($correct_answers_row[0]) || sizeof($correct_answers_row[0]) == 0) {
196 return false;
197 }
198 if ($correct_answers_row[1] > 0) {
199 array_push($points, $correct_answers_row[1]);
200 }
201 }
202 if (sizeof($correct_answers) != sizeof($points)) {
203 return false;
204 }
205
206 foreach ($points as $row) {
207 if ($row <= 0) {
208 return false;
209 }
210 }
211 return true;
212 }
213
219 private function correctAnswerDoesNotExistInAnswerOptions($answers, $answer_options)
220 {
221 foreach ($answers[0] as $key => $answer) {
222 if (!in_array($answer, $answer_options)) {
223 return true;
224 }
225 }
226 return false;
227 }
228
229
236 public function getMaximumPoints()
237 {
238 $sum = 0;
239 $points = $this->getCorrectAnswers();
240 if ($points) {
241 foreach ($points as $add) {
242 $sum += $add[1];
243 }
244 }
245 return $sum;
246 }
247
249 {
250 // save additional data
251 $this->ilDB->manipulateF(
252 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
253 array( "integer" ),
254 array( $this->getId() )
255 );
256 $this->ilDB->manipulateF(
257 "INSERT INTO " . $this->getAdditionalTableName(
258 ) . " (question_fi, long_menu_text, feedback_setting, min_auto_complete, identical_scoring) VALUES (%s, %s, %s, %s, %s)",
259 array( "integer", "text", "integer", "integer", "integer"),
260 array(
261 $this->getId(),
262 $this->getLongMenuTextValue(),
263 (int) $this->getSpecificFeedbackSetting(),
264 (int) $this->getMinAutoComplete(),
265 (int) $this->getIdenticalScoring()
266 )
267 );
268
269 $this->createFileFromArray();
270 }
271
273 {
274 $this->clearAnswerSpecificDataFromDb($this->getId());
275 $type_array = $this->getAnswerType();
276 $points = 0;
277 foreach ($this->getCorrectAnswers() as $gap_number => $gap) {
278 foreach ($gap[0] as $position => $answer) {
279 if ($type_array == null) {
280 $type = $gap[2];
281 } else {
282 $type = $type_array[$gap_number];
283 }
284 $this->db->replace(
285 $this->getAnswerTableName(),
286 array(
287 'question_fi' => array('integer', (int) $this->getId()),
288 'gap_number' => array('integer', (int) $gap_number),
289 'position' => array('integer', (int) $position)
290 ),
291 array(
292 'answer_text' => array('text', $answer),
293 'points' => array('float', $gap[1]),
294 'type' => array('integer', (int) $type)
295 )
296 );
297 }
298 $points += $gap[1];
299 }
300 $this->setPoints($points);
301 }
302
303 private function createFileFromArray()
304 {
305 $array = $this->getAnswers();
306 $this->clearFolder();
307 foreach ($array as $gap => $values) {
308 $file_content = '';
309 if (is_array($values)) {
310 foreach ($values as $key => $value) {
311 $file_content .= $value . "\n";
312 }
313 $file_content = rtrim($file_content, "\n");
314 $file = fopen($this->buildFileName($gap), "w");
315 fwrite($file, $file_content);
316 fclose($file);
317 }
318 }
319 }
320
321 private function createArrayFromFile()
322 {
323 $files = glob($this->buildFolderName() . '*.txt');
324
325 if ($files === false) {
326 $files = array();
327 }
328
329 $answers = array();
330
331 foreach ($files as $file) {
332 $gap = str_replace('.txt', '', basename($file));
333 $answers[(int) $gap] = explode("\n", file_get_contents($file));
334 }
335 $this->setAnswers($answers);
336 return $answers;
337 }
338
339 private function clearFolder($let_folder_exists = true)
340 {
341 ilUtil::delDir($this->buildFolderName(), $let_folder_exists);
342 }
343
344 private function assertDirExists()
345 {
346 $folder_name = $this->buildFolderName();
347 if (!ilUtil::makeDirParents($folder_name)) {
348 throw new ilException('Cannot create export directory');
349 }
350
351 if (
352 !is_dir($folder_name) ||
353 !is_readable($folder_name) ||
354 !is_writable($folder_name)
355 ) {
356 throw new ilException('Cannot create export directory');
357 }
358 }
359
360 public function loadFromDb($question_id)
361 {
362 $result = $this->ilDB->queryF(
363 "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",
364 array("integer"),
365 array($question_id)
366 );
367 if ($result->numRows() == 1) {
368 $data = $this->ilDB->fetchAssoc($result);
369 $this->setId($question_id);
370 $this->setObjId($data["obj_fi"]);
371 $this->setNrOfTries($data['nr_of_tries']);
372 $this->setTitle($data["title"]);
373 $this->setComment($data["description"]);
374 $this->setOriginalId($data["original_id"]);
375 $this->setAuthor($data["author"]);
376 $this->setPoints($data["points"]);
377 $this->setIdenticalScoring($data["identical_scoring"]);
378 $this->setOwner($data["owner"]);
379 include_once("./Services/RTE/classes/class.ilRTE.php");
380 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data['question_text'], 1));
381 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
383 $this->loadCorrectAnswerData($question_id);
384 $this->setMinAutoComplete($data["min_auto_complete"]);
385 if (isset($data['feedback_setting'])) {
386 $this->setSpecificFeedbackSetting((int) $data['feedback_setting']);
387 }
388
389 try {
393 }
394
395 try {
396 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
398 }
399 }
400
401 $this->loadCorrectAnswerData($question_id);
402 $this->createArrayFromFile();
403 parent::loadFromDb($question_id);
404 }
405
406 private function loadCorrectAnswerData($question_id)
407 {
408 $res = $this->db->queryF(
409 "SELECT * FROM {$this->getAnswerTableName()} WHERE question_fi = %s ORDER BY gap_number, position ASC",
410 array('integer'),
411 array($question_id)
412 );
413
414 $correct_answers = array();
415 while ($data = $this->ilDB->fetchAssoc($res)) {
416 $correct_answers[$data['gap_number']][0][$data['position']] = rtrim($data['answer_text']);
417 $correct_answers[$data['gap_number']][1] = $data['points'];
418 $correct_answers[$data['gap_number']][2] = $data['type'];
419 }
420 $this->setJsonStructure(json_encode($correct_answers));
422 }
423
424 public function getCorrectAnswersForQuestionSolution($question_id)
425 {
426 $correct_answers = array();
427 $res = $this->db->queryF(
428 'SELECT gap_number, answer_text FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s',
429 array('integer'),
430 array($question_id)
431 );
432 while ($data = $this->ilDB->fetchAssoc($res)) {
433 if (array_key_exists($data['gap_number'], $correct_answers)) {
434 $correct_answers[$data['gap_number']] .= ' ' . $this->lng->txt("or") . ' ';
435 $correct_answers[$data['gap_number']] .= rtrim($data['answer_text']);
436 } else {
437 $correct_answers[$data['gap_number']] .= rtrim($data['answer_text']);
438 }
439 }
440 return $correct_answers;
441 }
442
443 private function getCorrectAnswersForGap($question_id, $gap_id)
444 {
445 $correct_answers = array();
446 $res = $this->db->queryF(
447 'SELECT answer_text FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s AND gap_number = %s',
448 array('integer', 'integer'),
449 array($question_id, $gap_id)
450 );
451 while ($data = $this->ilDB->fetchAssoc($res)) {
452 $correct_answers[] = rtrim($data['answer_text']);
453 }
454 return $correct_answers;
455 }
456
457 private function getPointsForGap($question_id, $gap_id)
458 {
459 $points = 0;
460 $res = $this->db->queryF(
461 'SELECT points FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s AND gap_number = %s GROUP BY gap_number, points',
462 array('integer', 'integer'),
463 array($question_id, $gap_id)
464 );
465 while ($data = $this->ilDB->fetchAssoc($res)) {
466 $points = $data['points'];
467 }
468 return $points;
469 }
470
471
472 public function getAnswersObject()
473 {
474 return json_encode($this->createArrayFromFile());
475 }
476
477 public function getCorrectAnswersAsJson()
478 {
479 $this->loadCorrectAnswerData($this->getId());
480 return $this->getJsonStructure();
481 }
482
483 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
484 {
485 if ($this->id <= 0) {
486 // The question has not been saved. It cannot be duplicated
487 return;
488 }
489
490 // duplicate the question in database
491 $this_id = $this->getId();
492 $thisObjId = $this->getObjId();
493
494 $clone = $this;
495 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
497 $clone->id = -1;
498
499 if ((int) $testObjId > 0) {
500 $clone->setObjId($testObjId);
501 }
502
503 if ($title) {
504 $clone->setTitle($title);
505 }
506
507 if ($author) {
508 $clone->setAuthor($author);
509 }
510 if ($owner) {
511 $clone->setOwner($owner);
512 }
513
514 if ($for_test) {
515 $clone->saveToDb($original_id);
516 } else {
517 $clone->saveToDb();
518 }
519
520 $clone->copyPageOfQuestion($this_id);
521 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
522 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
523
524 return $clone->id;
525 }
526
527 public function copyObject($target_questionpool_id, $title = "")
528 {
529 if ($this->id <= 0) {
530 // The question has not been saved. It cannot be duplicated
531 return;
532 }
533 // duplicate the question in database
534 $clone = $this;
535 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
537 $clone->id = -1;
538 $source_questionpool_id = $this->getObjId();
539 $clone->setObjId($target_questionpool_id);
540 if ($title) {
541 $clone->setTitle($title);
542 }
543 $clone->saveToDb();
544
545 $clone->copyPageOfQuestion($original_id);
546 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
547
548 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
549
550 return $clone->id;
551 }
552
553 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
554 {
555 if ($this->id <= 0) {
556 // The question has not been saved. It cannot be duplicated
557 return;
558 }
559
560 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
561
562 $sourceQuestionId = $this->id;
563 $sourceParentId = $this->getObjId();
564
565 // duplicate the question in database
566 $clone = $this;
567 $clone->id = -1;
568
569 $clone->setObjId($targetParentId);
570
571 if ($targetQuestionTitle) {
572 $clone->setTitle($targetQuestionTitle);
573 }
574
575 $clone->saveToDb();
576 $clone->copyPageOfQuestion($sourceQuestionId);
577 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
578
579 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
580
581 return $clone->id;
582 }
583
584
596 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
597 {
598 if ($returndetails) {
599 throw new ilTestException('return details not implemented for ' . __METHOD__);
600 }
601
602 $found_values = array();
603 if (is_null($pass)) {
604 $pass = $this->getSolutionMaxPass($active_id);
605 }
606 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
607 while ($data = $this->ilDB->fetchAssoc($result)) {
608 $found_values[(int) $data['value1']] = $data['value2'];
609 }
610
611 $points = $this->calculateReachedPointsForSolution($found_values, $active_id);
612
613 return $points;
614 }
615
616 protected function calculateReachedPointsForSolution($found_values, $active_id = 0)
617 {
618 $points = 0;
619 $solution_values_text = array();
620 foreach ($found_values as $key => $answer) {
621 if ($answer != '') {
622 $correct_answers = $this->getCorrectAnswersForGap($this->id, $key);
623 if (in_array($answer, $correct_answers)) {
624 $points_gap = $this->getPointsForGap($this->id, $key);
625 if (!$this->getIdenticalScoring()) {
626 // check if the same solution text was already entered
627 if ((in_array($answer, $solution_values_text)) && ($points > 0)) {
628 $points_gap = 0;
629 }
630 }
631 $points += $points_gap;
632 array_push($solution_values_text, $answer);
633 }
634 }
635 }
636 return $points;
637 }
638
647 public function saveWorkingData($active_id, $pass = null, $authorized = true)
648 {
649 if (is_null($pass)) {
650 include_once "./Modules/Test/classes/class.ilObjTest.php";
651 $pass = ilObjTest::_getPass($active_id);
652 }
653
654 $entered_values = 0;
655
656 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized) {
657 $this->removeCurrentSolution($active_id, $pass, $authorized);
658
659 foreach ($this->getSolutionSubmit() as $val1 => $val2) {
660 $value = ilUtil::stripSlashes($val2, false);
661 if (strlen($value)) {
662 $this->saveCurrentSolution($active_id, $pass, $val1, $value, $authorized);
663 $entered_values++;
664 }
665 }
666 });
667
668 if ($entered_values) {
669 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
671 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
672 }
673 } else {
674 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
676 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
677 }
678 }
679 return true;
680 }
681
682 // fau: testNav - overridden function lookupForExistingSolutions (specific for long menu question: ignore unselected values)
689 public function lookupForExistingSolutions($activeId, $pass)
690 {
691 global $DIC;
692 $ilDB = $DIC['ilDB'];
693
694 $return = array(
695 'authorized' => false,
696 'intermediate' => false
697 );
698
699 $query = "
700 SELECT authorized, COUNT(*) cnt
701 FROM tst_solutions
702 WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
703 AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
704 AND pass = " . $ilDB->quote($pass, 'integer') . "
705 AND value2 <> '-1'
706 ";
707
708 if ($this->getStep() !== null) {
709 $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
710 }
711
712 $query .= "
713 GROUP BY authorized
714 ";
715
716 $result = $ilDB->query($query);
717
718 while ($row = $ilDB->fetchAssoc($result)) {
719 if ($row['authorized']) {
720 $return['authorized'] = $row['cnt'] > 0;
721 } else {
722 $return['intermediate'] = $row['cnt'] > 0;
723 }
724 }
725 return $return;
726 }
727 // fau.
728
729
730 public function getSolutionSubmit()
731 {
732 $solutionSubmit = array();
733 $answer = ilUtil::stripSlashesRecursive($_POST['answer']);
734
735 foreach ($answer as $key => $value) {
736 $solutionSubmit[$key] = $value;
737 }
738
739 return $solutionSubmit;
740 }
741
742 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
743 {
744 if (array_key_exists('answer', $_POST)) {
745 $previewSession->setParticipantsSolution($_POST['answer']);
746 } else {
747 $previewSession->setParticipantsSolution(null);
748 }
749 }
750
756 public function getQuestionType()
757 {
758 return "assLongMenu";
759 }
760
766 public function getAdditionalTableName()
767 {
768 return 'qpl_qst_lome';
769 }
770
776 {
777 return parent::getRTETextWithMediaObjects() . $this->getLongMenuTextValue();
778 }
779
783 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
784 {
785 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
786
787 $solution = $this->getSolutionValues($active_id, $pass);
788
789 $i = 1;
790 foreach ($this->getCorrectAnswers() as $gap_index => $gap) {
791 $worksheet->setCell($startrow + $i, 0, $this->lng->txt('assLongMenu') . " $i");
792 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
793 foreach ($solution as $solutionvalue) {
794 if ($gap_index == $solutionvalue["value1"]) {
795 switch ($gap[2]) {
797 $value = $solutionvalue["value2"];
798 if ($value == -1) {
799 $value = '';
800 }
801 $worksheet->setCell($startrow + $i, 1, $value);
802 break;
804 $worksheet->setCell($startrow + $i, 1, $solutionvalue["value2"]);
805 break;
806 }
807 }
808 }
809 $i++;
810 }
811
812 return $startrow + $i + 1;
813 }
814
823 public function getUserQuestionResult($active_id, $pass)
824 {
825 $result = new ilUserQuestionResult($this, $active_id, $pass);
826
827 $points = $this->calculateReachedPoints($active_id, $pass);
828 $max_points = $this->getMaximumPoints();
829
830 $result->setReachedPercentage(($points / $max_points) * 100);
831
832 return $result;
833 }
834
843 public function getAvailableAnswerOptions($index = null)
844 {
845 return $this->createArrayFromFile();
846 }
847
848 public function isShuffleAnswersEnabled()
849 {
850 return false;
851 }
852
853 public function clearAnswerSpecificDataFromDb($question_id)
854 {
855 $this->ilDB->manipulateF(
856 'DELETE FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s',
857 array( 'integer' ),
858 array( $question_id )
859 );
860 }
861
862 public function delete($original_id)
863 {
864 parent::delete($original_id);
865 $this->clearFolder(false);
866 }
867
872 {
873 $this->setLongMenuTextValue($migrator->migrateToLmContent($this->getLongMenuTextValue()));
874 }
875
879 public function toJSON()
880 {
881 include_once("./Services/RTE/classes/class.ilRTE.php");
882 $result = array();
883 $result['id'] = (int) $this->getId();
884 $result['type'] = (string) $this->getQuestionType();
885 $result['title'] = (string) $this->getTitle();
886 $replaced_quesiton_text = $this->getLongMenuTextValue();
887 $result['question'] = $this->formatSAQuestion($this->getQuestion());
888 $result['lmtext'] = $this->formatSAQuestion($replaced_quesiton_text);
889 $result['nr_of_tries'] = (int) $this->getNrOfTries();
890 $result['shuffle'] = (bool) $this->getShuffle();
891 $result['feedback'] = array(
892 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
893 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
894 );
895
896 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
897 $result['answers'] = $this->getAnswers();
898 $result['correct_answers'] = $this->getCorrectAnswers();
899 $result['mobs'] = $mobs;
900 return json_encode($result);
901 }
902
903 public function getIdenticalScoring()
904 {
905 return ($this->identical_scoring) ? 1 : 0;
906 }
907
911 public function setIdenticalScoring($a_identical_scoring)
912 {
913 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
914 }
915}
$result
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
loadCorrectAnswerData($question_id)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
checkQuestionCustomPart($form=null)
const MIN_LENGTH_AUTOCOMPLETE
copyObject($target_questionpool_id, $title="")
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
calculateReachedPointsForSolution($found_values, $active_id=0)
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
setIdenticalScoring($a_identical_scoring)
getAdditionalTableName()
Returns the name of the additional question data table in the database.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
getCorrectAnswersForGap($question_id, $gap_id)
setLongMenuTextValue($long_menu_text="")
isComplete()
Returns true, if a question is complete for use.
const ANSWER_TYPE_TEXT_VAL
buildFileName($gap_id)
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
getQuestionType()
Returns the question type of the question.
const ANSWER_TYPE_SELECT_VAL
toJSON()
Returns a JSON representation of the question.
getPointsForGap($question_id, $gap_id)
clearFolder($let_folder_exists=true)
loadFromDb($question_id)
Loads the question from the database.
setMinAutoComplete($minAutoComplete)
clearAnswerSpecificDataFromDb($question_id)
saveToDb($original_id="")
Saves the question to the database.
setAnswerType($answerType)
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assQuestion constructor
setSpecificFeedbackSetting($specificFeedbackSetting)
setCorrectAnswers($correct_answers)
getAnswerTableName()
Returns the name of the answer table in the database.
lookupForExistingSolutions($activeId, $pass)
Lookup if an authorized or intermediate solution exists.
correctAnswerDoesNotExistInAnswerOptions($answers, $answer_options)
getCorrectAnswersForQuestionSolution($question_id)
savePreviewData(ilAssQuestionPreviewSession $previewSession)
setJsonStructure($json_structure)
setAnswers($answers)
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
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.
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)
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.
Base class for ILIAS Exception handling.
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
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...
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
static getDataDir()
get data directory (outside webspace)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static stripSlashesRecursive($a_data, $a_strip_html=true, $a_allow="")
Strip slashes from array and sub-arrays.
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static makeDirParents($a_dir)
Create a new directory and all parent directories.
Interface ilObjQuestionScoringAdjustable.
$index
Definition: metadata.php:128
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$query
$type
foreach($_POST as $key=> $value) $res
$data
Definition: storeScorm.php:23
$mobs
$DIC
Definition: xapitoken.php:46