ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7 require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
8 require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
9 
10 
12 {
13  private $answerType;
14  private $long_menu_text;
15  private $json_structure;
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;
44  parent::__construct($title, $comment, $author, $owner, $question);
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 
98  public function setLongMenuTextValue($long_menu_text = "")
99  {
100  $this->long_menu_text = $long_menu_text;
101  }
102 
103  public function getLongMenuTextValue()
104  {
105  return $this->long_menu_text;
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  {
123  return $this->json_structure;
124  }
125 
130  {
131  $this->json_structure = $json_structure;
132  }
133 
135  {
136  $this->specificFeedbackSetting = $specificFeedbackSetting;
137  }
138 
139  public function getSpecificFeedbackSetting()
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 
272  public function saveAnswerSpecificDataToDb()
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));
382  $this->setLongMenuTextValue(ilRTE::_replaceMediaObjectImageSrc($data['long_menu_text'], 1));
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  try {
389  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
390  } catch (ilTestQuestionPoolException $e) {
391  }
392  }
393 
394  $this->loadCorrectAnswerData($question_id);
395  $this->createArrayFromFile();
396  parent::loadFromDb($question_id);
397  }
398 
399  private function loadCorrectAnswerData($question_id)
400  {
401  $res = $this->db->queryF(
402  "SELECT * FROM {$this->getAnswerTableName()} WHERE question_fi = %s ORDER BY gap_number, position ASC",
403  array('integer'),
404  array($question_id)
405  );
406 
407  $correct_answers = array();
408  while ($data = $this->ilDB->fetchAssoc($res)) {
409  $correct_answers[$data['gap_number']][0][$data['position']] = rtrim($data['answer_text']);
410  $correct_answers[$data['gap_number']][1] = $data['points'];
411  $correct_answers[$data['gap_number']][2] = $data['type'];
412  }
413  $this->setJsonStructure(json_encode($correct_answers));
415  }
416 
417  public function getCorrectAnswersForQuestionSolution($question_id)
418  {
419  $correct_answers = array();
420  $res = $this->db->queryF(
421  'SELECT gap_number, answer_text FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s',
422  array('integer'),
423  array($question_id)
424  );
425  while ($data = $this->ilDB->fetchAssoc($res)) {
426  if (array_key_exists($data['gap_number'], $correct_answers)) {
427  $correct_answers[$data['gap_number']] .= ' ' . $this->lng->txt("or") . ' ';
428  $correct_answers[$data['gap_number']] .= rtrim($data['answer_text']);
429  } else {
430  $correct_answers[$data['gap_number']] .= rtrim($data['answer_text']);
431  }
432  }
433  return $correct_answers;
434  }
435 
436  private function getCorrectAnswersForGap($question_id, $gap_id)
437  {
438  $correct_answers = array();
439  $res = $this->db->queryF(
440  'SELECT answer_text FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s AND gap_number = %s',
441  array('integer', 'integer'),
442  array($question_id, $gap_id)
443  );
444  while ($data = $this->ilDB->fetchAssoc($res)) {
445  $correct_answers[] = rtrim($data['answer_text']);
446  }
447  return $correct_answers;
448  }
449 
450  private function getPointsForGap($question_id, $gap_id)
451  {
452  $points = 0;
453  $res = $this->db->queryF(
454  'SELECT points FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s AND gap_number = %s GROUP BY gap_number, points',
455  array('integer', 'integer'),
456  array($question_id, $gap_id)
457  );
458  while ($data = $this->ilDB->fetchAssoc($res)) {
459  $points = $data['points'];
460  }
461  return $points;
462  }
463 
464 
465  public function getAnswersObject()
466  {
467  return json_encode($this->createArrayFromFile());
468  }
469 
470  public function getCorrectAnswersAsJson()
471  {
472  $this->loadCorrectAnswerData($this->getId());
473  return $this->getJsonStructure();
474  }
475 
476  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
477  {
478  if ($this->id <= 0) {
479  // The question has not been saved. It cannot be duplicated
480  return;
481  }
482 
483  // duplicate the question in database
484  $this_id = $this->getId();
485  $thisObjId = $this->getObjId();
486 
487  $clone = $this;
488  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
490  $clone->id = -1;
491 
492  if ((int) $testObjId > 0) {
493  $clone->setObjId($testObjId);
494  }
495 
496  if ($title) {
497  $clone->setTitle($title);
498  }
499 
500  if ($author) {
501  $clone->setAuthor($author);
502  }
503  if ($owner) {
504  $clone->setOwner($owner);
505  }
506 
507  if ($for_test) {
508  $clone->saveToDb($original_id);
509  } else {
510  $clone->saveToDb();
511  }
512 
513  $clone->copyPageOfQuestion($this_id);
514  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
515  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
516 
517  return $clone->id;
518  }
519 
520  public function copyObject($target_questionpool_id, $title = "")
521  {
522  if ($this->id <= 0) {
523  // The question has not been saved. It cannot be duplicated
524  return;
525  }
526  // duplicate the question in database
527  $clone = $this;
528  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
530  $clone->id = -1;
531  $source_questionpool_id = $this->getObjId();
532  $clone->setObjId($target_questionpool_id);
533  if ($title) {
534  $clone->setTitle($title);
535  }
536  $clone->saveToDb();
537 
538  $clone->copyPageOfQuestion($original_id);
539  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
540 
541  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
542 
543  return $clone->id;
544  }
545 
546  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
547  {
548  if ($this->id <= 0) {
549  // The question has not been saved. It cannot be duplicated
550  return;
551  }
552 
553  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
554 
555  $sourceQuestionId = $this->id;
556  $sourceParentId = $this->getObjId();
557 
558  // duplicate the question in database
559  $clone = $this;
560  $clone->id = -1;
561 
562  $clone->setObjId($targetParentId);
563 
564  if ($targetQuestionTitle) {
565  $clone->setTitle($targetQuestionTitle);
566  }
567 
568  $clone->saveToDb();
569  $clone->copyPageOfQuestion($sourceQuestionId);
570  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
571 
572  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
573 
574  return $clone->id;
575  }
576 
577 
589  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
590  {
591  if ($returndetails) {
592  throw new ilTestException('return details not implemented for ' . __METHOD__);
593  }
594 
595  $found_values = array();
596  if (is_null($pass)) {
597  $pass = $this->getSolutionMaxPass($active_id);
598  }
599  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
600  while ($data = $this->ilDB->fetchAssoc($result)) {
601  $found_values[(int) $data['value1']] = $data['value2'];
602  }
603 
604  $points = $this->calculateReachedPointsForSolution($found_values, $active_id);
605 
606  return $points;
607  }
608 
609  protected function calculateReachedPointsForSolution($found_values, $active_id = 0)
610  {
611  $points = 0;
612  $solution_values_text = array();
613  foreach ($found_values as $key => $answer) {
614  if ($answer != '') {
615  $correct_answers = $this->getCorrectAnswersForGap($this->id, $key);
616  if (in_array($answer, $correct_answers)) {
617  $points_gap = $this->getPointsForGap($this->id, $key);
618  if (!$this->getIdenticalScoring()) {
619  // check if the same solution text was already entered
620  if ((in_array($answer, $solution_values_text)) && ($points > 0)) {
621  $points_gap = 0;
622  }
623  }
624  $points += $points_gap;
625  array_push($solution_values_text, $answer);
626  }
627  }
628  }
629  return $points;
630  }
631 
640  public function saveWorkingData($active_id, $pass = null, $authorized = true)
641  {
642  if (is_null($pass)) {
643  include_once "./Modules/Test/classes/class.ilObjTest.php";
644  $pass = ilObjTest::_getPass($active_id);
645  }
646 
647  $entered_values = 0;
648 
649  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $active_id, $pass, $authorized) {
650  $this->removeCurrentSolution($active_id, $pass, $authorized);
651 
652  foreach ($this->getSolutionSubmit() as $val1 => $val2) {
653  $value = ilUtil::stripSlashes($val2, false);
654  if (strlen($value)) {
655  $this->saveCurrentSolution($active_id, $pass, $val1, $value, $authorized);
656  $entered_values++;
657  }
658  }
659  });
660 
661  if ($entered_values) {
662  include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
664  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
665  }
666  } else {
667  include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
669  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
670  }
671  }
672  return true;
673  }
674 
675  // fau: testNav - overridden function lookupForExistingSolutions (specific for long menu question: ignore unselected values)
682  public function lookupForExistingSolutions($activeId, $pass)
683  {
684  global $DIC;
685  $ilDB = $DIC['ilDB'];
686 
687  $return = array(
688  'authorized' => false,
689  'intermediate' => false
690  );
691 
692  $query = "
693  SELECT authorized, COUNT(*) cnt
694  FROM tst_solutions
695  WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
696  AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
697  AND pass = " . $ilDB->quote($pass, 'integer') . "
698  AND value2 <> '-1'
699  ";
700 
701  if ($this->getStep() !== null) {
702  $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
703  }
704 
705  $query .= "
706  GROUP BY authorized
707  ";
708 
709  $result = $ilDB->query($query);
710 
711  while ($row = $ilDB->fetchAssoc($result)) {
712  if ($row['authorized']) {
713  $return['authorized'] = $row['cnt'] > 0;
714  } else {
715  $return['intermediate'] = $row['cnt'] > 0;
716  }
717  }
718  return $return;
719  }
720  // fau.
721 
722 
723  public function getSolutionSubmit()
724  {
725  $solutionSubmit = array();
726  $answer = ilUtil::stripSlashesRecursive($_POST['answer']);
727 
728  foreach ($answer as $key => $value) {
729  $solutionSubmit[$key] = $value;
730  }
731 
732  return $solutionSubmit;
733  }
734 
735  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
736  {
737  if (array_key_exists('answer', $_POST)) {
738  $previewSession->setParticipantsSolution($_POST['answer']);
739  } else {
740  $previewSession->setParticipantsSolution(null);
741  }
742  }
743 
749  public function getQuestionType()
750  {
751  return "assLongMenu";
752  }
753 
759  public function getAdditionalTableName()
760  {
761  return 'qpl_qst_lome';
762  }
763 
768  public function getRTETextWithMediaObjects()
769  {
770  return parent::getRTETextWithMediaObjects() . $this->getLongMenuTextValue();
771  }
772 
776  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
777  {
778  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
779 
780  $solution = $this->getSolutionValues($active_id, $pass);
781 
782  $i = 1;
783  foreach ($this->getCorrectAnswers() as $gap_index => $gap) {
784  $worksheet->setCell($startrow + $i, 0, $this->lng->txt('assLongMenu') . " $i");
785  $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
786  foreach ($solution as $solutionvalue) {
787  if ($gap_index == $solutionvalue["value1"]) {
788  switch ($gap[2]) {
789  case self::ANSWER_TYPE_SELECT_VAL:
790  $value = $solutionvalue["value2"];
791  if ($value == -1) {
792  $value = '';
793  }
794  $worksheet->setCell($startrow + $i, 1, $value);
795  break;
796  case self::ANSWER_TYPE_TEXT_VAL:
797  $worksheet->setCell($startrow + $i, 1, $solutionvalue["value2"]);
798  break;
799  }
800  }
801  }
802  $i++;
803  }
804 
805  return $startrow + $i + 1;
806  }
807 
816  public function getUserQuestionResult($active_id, $pass)
817  {
818  $result = new ilUserQuestionResult($this, $active_id, $pass);
819 
820  $points = $this->calculateReachedPoints($active_id, $pass);
821  $max_points = $this->getMaximumPoints();
822 
823  $result->setReachedPercentage(($points / $max_points) * 100);
824 
825  return $result;
826  }
827 
836  public function getAvailableAnswerOptions($index = null)
837  {
838  return $this->createArrayFromFile();
839  }
840 
841  public function isShuffleAnswersEnabled()
842  {
843  return false;
844  }
845 
846  public function clearAnswerSpecificDataFromDb($question_id)
847  {
848  $this->ilDB->manipulateF(
849  'DELETE FROM ' . $this->getAnswerTableName() . ' WHERE question_fi = %s',
850  array( 'integer' ),
851  array( $question_id )
852  );
853  }
854 
855  public function delete($original_id)
856  {
857  parent::delete($original_id);
858  $this->clearFolder(false);
859  }
860 
865  {
866  $this->setLongMenuTextValue($migrator->migrateToLmContent($this->getLongMenuTextValue()));
867  }
868 
872  public function toJSON()
873  {
874  include_once("./Services/RTE/classes/class.ilRTE.php");
875  $result = array();
876  $result['id'] = (int) $this->getId();
877  $result['type'] = (string) $this->getQuestionType();
878  $result['title'] = (string) $this->getTitle();
879  $replaced_quesiton_text = $this->getLongMenuTextValue();
880  $result['question'] = $this->formatSAQuestion($this->getQuestion());
881  $result['lmtext'] = $this->formatSAQuestion($replaced_quesiton_text);
882  $result['nr_of_tries'] = (int) $this->getNrOfTries();
883  $result['shuffle'] = (bool) $this->getShuffle();
884  $result['feedback'] = array(
885  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
886  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
887  );
888 
889  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
890  $result['answers'] = $this->getAnswers();
891  $result['correct_answers'] = $this->getCorrectAnswers();
892  $result['mobs'] = $mobs;
893  return json_encode($result);
894  }
895 
896  public function getIdenticalScoring()
897  {
898  return ($this->identical_scoring) ? 1 : 0;
899  }
900 
904  public function setIdenticalScoring($a_identical_scoring)
905  {
906  $this->identical_scoring = ($a_identical_scoring) ? 1 : 0;
907  }
908 }
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
correctAnswerDoesNotExistInAnswerOptions($answers, $answer_options)
getId()
Gets the id of the assQuestion object.
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
setAnswers($answers)
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
getCorrectAnswersForQuestionSolution($question_id)
setIdenticalScoring($a_identical_scoring)
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
$files
Definition: metarefresh.php:49
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
setAnswerType($answerType)
$result
getCorrectAnswersForGap($question_id, $gap_id)
getPoints()
Returns the maximum available points for the question.
$type
global $DIC
Definition: saml.php:7
setMinAutoComplete($minAutoComplete)
setJsonStructure($json_structure)
Abstract basic class which is to be extended by the concrete assessment question type classes...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
checkQuestionCustomPart($form=null)
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
setId($id=-1)
Sets the id of the assQuestion object.
setSpecificFeedbackSetting($specificFeedbackSetting)
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
$index
Definition: metadata.php:60
calculateReachedPointsForSolution($found_values, $active_id=0)
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
loadCorrectAnswerData($question_id)
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...
getObjId()
Get the object id of the container object.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
getShuffle()
Gets the shuffle flag.
Base Exception for all Exceptions relating to Modules/Test.
saveToDb($original_id="")
const MIN_LENGTH_AUTOCOMPLETE
static _getLogLanguage()
retrieve the log language for assessment logging
copyObject($target_questionpool_id, $title="")
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
const ANSWER_TYPE_TEXT_VAL
setAuthor($author="")
Sets the authors name of the assQuestion object.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
setLongMenuTextValue($long_menu_text="")
foreach($_POST as $key=> $value) $res
if(isset($_POST['submit'])) $form
$mobs
Class ilUserQuestionResult.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
$values
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
loadFromDb($question_id)
static stripSlashesRecursive($a_data, $a_strip_html=true, $a_allow="")
Strip slashes from array and sub-arrays.
toJSON()
Returns a JSON representation of the question.
getQuestion()
Gets the question string of the question object.
$query
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
getPointsForGap($question_id, $gap_id)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
$row
lookupForExistingSolutions($activeId, $pass)
Lookup if an authorized or intermediate solution exists.
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
static getDataDir()
get data directory (outside webspace)
clearAnswerSpecificDataFromDb($question_id)
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
getQuestionType()
Returns the question type of the question.
setOriginalId($original_id)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
$i
Definition: disco.tpl.php:19
getTitle()
Gets the title string of the assQuestion object.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
clearFolder($let_folder_exists=true)
const ANSWER_TYPE_SELECT_VAL
$key
Definition: croninfo.php:18
setComment($comment="")
Sets the comment string of the assQuestion object.
$_POST["username"]
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
setCorrectAnswers($correct_answers)
buildFileName($gap_id)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
$data
Definition: bench.php:6