ILIAS  release_7 Revision v7.30-3-g800a261c036
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 // Sort by gap keys, to ensure the numbers are in ascending order.
336 // Glob will report the keys in files order like 0, 1, 10, 11, 2,...
337 // json_encoding the array with keys in order 0,1,10,11,2,.. will create
338 // a json_object instead of a list when keys are numeric, sorted and start with 0
339 ksort($answers);
340 $this->setAnswers($answers);
341 return $answers;
342 }
343
344 private function clearFolder($let_folder_exists = true)
345 {
346 ilUtil::delDir($this->buildFolderName(), $let_folder_exists);
347 }
348
349 private function assertDirExists()
350 {
351 $folder_name = $this->buildFolderName();
352 if (!ilUtil::makeDirParents($folder_name)) {
353 throw new ilException('Cannot create export directory');
354 }
355
356 if (
357 !is_dir($folder_name) ||
358 !is_readable($folder_name) ||
359 !is_writable($folder_name)
360 ) {
361 throw new ilException('Cannot create export directory');
362 }
363 }
364
365 public function loadFromDb($question_id)
366 {
367 $result = $this->ilDB->queryF(
368 "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",
369 array("integer"),
370 array($question_id)
371 );
372 if ($result->numRows() == 1) {
373 $data = $this->ilDB->fetchAssoc($result);
374 $this->setId($question_id);
375 $this->setObjId($data["obj_fi"]);
376 $this->setNrOfTries($data['nr_of_tries']);
377 $this->setTitle($data["title"]);
378 $this->setComment($data["description"]);
379 $this->setOriginalId($data["original_id"]);
380 $this->setAuthor($data["author"]);
381 $this->setPoints($data["points"]);
382 $this->setIdenticalScoring($data["identical_scoring"]);
383 $this->setOwner($data["owner"]);
384 include_once("./Services/RTE/classes/class.ilRTE.php");
385 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data['question_text'], 1));
386 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
388 $this->loadCorrectAnswerData($question_id);
389 $this->setMinAutoComplete($data["min_auto_complete"]);
390 if (isset($data['feedback_setting'])) {
391 $this->setSpecificFeedbackSetting((int) $data['feedback_setting']);
392 }
393
394 try {
398 }
399
400 try {
401 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
403 }
404 }
405
406 $this->loadCorrectAnswerData($question_id);
407 $this->createArrayFromFile();
408 parent::loadFromDb($question_id);
409 }
410
411 private function loadCorrectAnswerData($question_id)
412 {
413 $res = $this->db->queryF(
414 "SELECT * FROM {$this->getAnswerTableName()} WHERE question_fi = %s ORDER BY gap_number, position ASC",
415 array('integer'),
416 array($question_id)
417 );
418
419 $correct_answers = array();
420 while ($data = $this->ilDB->fetchAssoc($res)) {
421 $correct_answers[$data['gap_number']][0][$data['position']] = rtrim($data['answer_text']);
422 $correct_answers[$data['gap_number']][1] = $data['points'];
423 $correct_answers[$data['gap_number']][2] = $data['type'];
424 }
425 $this->setJsonStructure(json_encode($correct_answers));
427 }
428
429 public function getCorrectAnswersForQuestionSolution($question_id)
430 {
431 $correct_answers = array();
432 $res = $this->db->queryF(
433 'SELECT gap_number, answer_text FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s',
434 array('integer'),
435 array($question_id)
436 );
437 while ($data = $this->ilDB->fetchAssoc($res)) {
438 if (array_key_exists($data['gap_number'], $correct_answers)) {
439 $correct_answers[$data['gap_number']] .= ' ' . $this->lng->txt("or") . ' ';
440 $correct_answers[$data['gap_number']] .= rtrim($data['answer_text']);
441 } else {
442 $correct_answers[$data['gap_number']] .= rtrim($data['answer_text']);
443 }
444 }
445 return $correct_answers;
446 }
447
448 private function getCorrectAnswersForGap($question_id, $gap_id)
449 {
450 $correct_answers = array();
451 $res = $this->db->queryF(
452 'SELECT answer_text FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s AND gap_number = %s',
453 array('integer', 'integer'),
454 array($question_id, $gap_id)
455 );
456 while ($data = $this->ilDB->fetchAssoc($res)) {
457 $correct_answers[] = rtrim($data['answer_text']);
458 }
459 return $correct_answers;
460 }
461
462 private function getPointsForGap($question_id, $gap_id)
463 {
464 $points = 0;
465 $res = $this->db->queryF(
466 'SELECT points FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s AND gap_number = %s GROUP BY gap_number, points',
467 array('integer', 'integer'),
468 array($question_id, $gap_id)
469 );
470 while ($data = $this->ilDB->fetchAssoc($res)) {
471 $points = $data['points'];
472 }
473 return $points;
474 }
475
476
477 public function getAnswersObject()
478 {
479 return json_encode($this->createArrayFromFile());
480 }
481
482 public function getCorrectAnswersAsJson()
483 {
484 $this->loadCorrectAnswerData($this->getId());
485 return $this->getJsonStructure();
486 }
487
488 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
489 {
490 if ($this->id <= 0) {
491 // The question has not been saved. It cannot be duplicated
492 return;
493 }
494
495 // duplicate the question in database
496 $this_id = $this->getId();
497 $thisObjId = $this->getObjId();
498
499 $clone = $this;
500 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
502 $clone->id = -1;
503
504 if ((int) $testObjId > 0) {
505 $clone->setObjId($testObjId);
506 }
507
508 if ($title) {
509 $clone->setTitle($title);
510 }
511
512 if ($author) {
513 $clone->setAuthor($author);
514 }
515 if ($owner) {
516 $clone->setOwner($owner);
517 }
518
519 if ($for_test) {
520 $clone->saveToDb($original_id);
521 } else {
522 $clone->saveToDb();
523 }
524
525 $clone->copyPageOfQuestion($this_id);
526 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
527 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
528
529 return $clone->id;
530 }
531
532 public function copyObject($target_questionpool_id, $title = "")
533 {
534 if ($this->id <= 0) {
535 // The question has not been saved. It cannot be duplicated
536 return;
537 }
538 // duplicate the question in database
539 $clone = $this;
540 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
542 $clone->id = -1;
543 $source_questionpool_id = $this->getObjId();
544 $clone->setObjId($target_questionpool_id);
545 if ($title) {
546 $clone->setTitle($title);
547 }
548 $clone->saveToDb();
549
550 $clone->copyPageOfQuestion($original_id);
551 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
552
553 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
554
555 return $clone->id;
556 }
557
558 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
559 {
560 if ($this->id <= 0) {
561 // The question has not been saved. It cannot be duplicated
562 return;
563 }
564
565 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
566
567 $sourceQuestionId = $this->id;
568 $sourceParentId = $this->getObjId();
569
570 // duplicate the question in database
571 $clone = $this;
572 $clone->id = -1;
573
574 $clone->setObjId($targetParentId);
575
576 if ($targetQuestionTitle) {
577 $clone->setTitle($targetQuestionTitle);
578 }
579
580 $clone->saveToDb();
581 $clone->copyPageOfQuestion($sourceQuestionId);
582 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
583
584 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
585
586 return $clone->id;
587 }
588
589
601 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
602 {
603 if ($returndetails) {
604 throw new ilTestException('return details not implemented for ' . __METHOD__);
605 }
606
607 $found_values = array();
608 if (is_null($pass)) {
609 $pass = $this->getSolutionMaxPass($active_id);
610 }
611 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
612 while ($data = $this->ilDB->fetchAssoc($result)) {
613 $found_values[(int) $data['value1']] = $data['value2'];
614 }
615
616 $points = $this->calculateReachedPointsForSolution($found_values, $active_id);
617
618 return $points;
619 }
620
621 protected function calculateReachedPointsForSolution($found_values, $active_id = 0)
622 {
623 $points = 0;
624 $solution_values_text = array();
625 foreach ($found_values as $key => $answer) {
626 if ($answer != '') {
627 $correct_answers = $this->getCorrectAnswersForGap($this->id, $key);
628 if (in_array($answer, $correct_answers)) {
629 $points_gap = $this->getPointsForGap($this->id, $key);
630 if (!$this->getIdenticalScoring()) {
631 // check if the same solution text was already entered
632 if ((in_array($answer, $solution_values_text)) && ($points > 0)) {
633 $points_gap = 0;
634 }
635 }
636 $points += $points_gap;
637 array_push($solution_values_text, $answer);
638 }
639 }
640 }
641 return $points;
642 }
643
652 public function saveWorkingData($active_id, $pass = null, $authorized = true)
653 {
654 if (is_null($pass)) {
655 include_once "./Modules/Test/classes/class.ilObjTest.php";
656 $pass = ilObjTest::_getPass($active_id);
657 }
658
659 $entered_values = 0;
660
661 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized) {
662 $this->removeCurrentSolution($active_id, $pass, $authorized);
663
664 foreach ($this->getSolutionSubmit() as $val1 => $val2) {
665 $value = ilUtil::stripSlashes(trim($val2), false);
666 if (strlen($value)) {
667 $this->saveCurrentSolution($active_id, $pass, $val1, $value, $authorized);
668 $entered_values++;
669 }
670 }
671 });
672
673 if ($entered_values) {
674 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
676 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
677 }
678 } else {
679 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
681 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
682 }
683 }
684 return true;
685 }
686
687 // fau: testNav - overridden function lookupForExistingSolutions (specific for long menu question: ignore unselected values)
694 public function lookupForExistingSolutions($activeId, $pass)
695 {
696 global $DIC;
697 $ilDB = $DIC['ilDB'];
698
699 $return = array(
700 'authorized' => false,
701 'intermediate' => false
702 );
703
704 $query = "
705 SELECT authorized, COUNT(*) cnt
706 FROM tst_solutions
707 WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
708 AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
709 AND pass = " . $ilDB->quote($pass, 'integer') . "
710 AND value2 <> '-1'
711 ";
712
713 if ($this->getStep() !== null) {
714 $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
715 }
716
717 $query .= "
718 GROUP BY authorized
719 ";
720
721 $result = $ilDB->query($query);
722
723 while ($row = $ilDB->fetchAssoc($result)) {
724 if ($row['authorized']) {
725 $return['authorized'] = $row['cnt'] > 0;
726 } else {
727 $return['intermediate'] = $row['cnt'] > 0;
728 }
729 }
730 return $return;
731 }
732 // fau.
733
734
735 public function getSolutionSubmit()
736 {
737 $solutionSubmit = array();
738 $answer = ilUtil::stripSlashesRecursive($_POST['answer']);
739
740 foreach ($answer as $key => $value) {
741 $solutionSubmit[$key] = $value;
742 }
743
744 return $solutionSubmit;
745 }
746
747 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
748 {
749 if (array_key_exists('answer', $_POST)) {
750 $previewSession->setParticipantsSolution(array_map(function ($value) {
751 return trim($value);
752 }, $_POST['answer']));
753 } else {
754 $previewSession->setParticipantsSolution(null);
755 }
756 }
757
763 public function getQuestionType()
764 {
765 return "assLongMenu";
766 }
767
773 public function getAdditionalTableName()
774 {
775 return 'qpl_qst_lome';
776 }
777
783 {
784 return parent::getRTETextWithMediaObjects() . $this->getLongMenuTextValue();
785 }
786
790 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
791 {
792 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
793
794 $solution = $this->getSolutionValues($active_id, $pass);
795
796 $i = 1;
797 foreach ($this->getCorrectAnswers() as $gap_index => $gap) {
798 $worksheet->setCell($startrow + $i, 0, $this->lng->txt('assLongMenu') . " $i");
799 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
800 foreach ($solution as $solutionvalue) {
801 if ($gap_index == $solutionvalue["value1"]) {
802 switch ($gap[2]) {
804 $value = $solutionvalue["value2"];
805 if ($value == -1) {
806 $value = '';
807 }
808 $worksheet->setCell($startrow + $i, 2, $value);
809 break;
811 $worksheet->setCell($startrow + $i, 2, $solutionvalue["value2"]);
812 break;
813 }
814 }
815 }
816 $i++;
817 }
818
819 return $startrow + $i + 1;
820 }
821
830 public function getUserQuestionResult($active_id, $pass)
831 {
832 $result = new ilUserQuestionResult($this, $active_id, $pass);
833
834 $points = $this->calculateReachedPoints($active_id, $pass);
835 $max_points = $this->getMaximumPoints();
836
837 $result->setReachedPercentage(($points / $max_points) * 100);
838
839 return $result;
840 }
841
850 public function getAvailableAnswerOptions($index = null)
851 {
852 return $this->createArrayFromFile();
853 }
854
855 public function isShuffleAnswersEnabled()
856 {
857 return false;
858 }
859
860 public function clearAnswerSpecificDataFromDb($question_id)
861 {
862 $this->ilDB->manipulateF(
863 'DELETE FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s',
864 array( 'integer' ),
865 array( $question_id )
866 );
867 }
868
869 public function delete($original_id)
870 {
871 parent::delete($original_id);
872 $this->clearFolder(false);
873 }
874
879 {
880 $this->setLongMenuTextValue($migrator->migrateToLmContent($this->getLongMenuTextValue()));
881 }
882
886 public function toJSON()
887 {
888 include_once("./Services/RTE/classes/class.ilRTE.php");
889 $result = array();
890 $result['id'] = (int) $this->getId();
891 $result['type'] = (string) $this->getQuestionType();
892 $result['title'] = (string) $this->getTitle();
893 $replaced_quesiton_text = $this->getLongMenuTextValue();
894 $result['question'] = $this->formatSAQuestion($this->getQuestion());
895 $result['lmtext'] = $this->formatSAQuestion($replaced_quesiton_text);
896 $result['nr_of_tries'] = (int) $this->getNrOfTries();
897 $result['shuffle'] = (bool) $this->getShuffle();
898 $result['feedback'] = array(
899 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
900 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
901 );
902
903 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
904 $result['answers'] = $this->getAnswers();
905 $result['correct_answers'] = $this->getCorrectAnswers();
906 $result['mobs'] = $mobs;
907 return json_encode($result);
908 }
909
910 public function getIdenticalScoring()
911 {
912 return ($this->identical_scoring) ? 1 : 0;
913 }
914
918 public function setIdenticalScoring($a_identical_scoring)
919 {
920 $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
921 }
922}
$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="")
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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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.
global $DIC
Definition: goto.php:24
$mobs
Definition: imgupload.php:54
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