ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5
class.assSingleChoice.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.ilObjAnswerScoringAdjustable.php';
8 require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9 require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
10 require_once 'Modules/TestQuestionPool/interfaces/interface.ilAssSpecificFeedbackOptionLabelProvider.php';
11 
26 {
34  var $answers;
35 
45 
51  protected $thumb_size;
52 
59  protected $feedback_setting;
60 
75  public function __construct(
76  $title = "",
77  $comment = "",
78  $author = "",
79  $owner = -1,
80  $question = "",
81  $output_type = OUTPUT_ORDER
82  )
83  {
84  parent::__construct($title, $comment, $author, $owner, $question);
85  $this->thumb_size = 150;
86  $this->output_type = $output_type;
87  $this->answers = array();
88  $this->shuffle = 1;
89  $this->feedback_setting = 2;
90  }
91 
98  function isComplete()
99  {
100  if (strlen($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
101  {
102  foreach ($this->answers as $answer)
103  {
104  if ((strlen($answer->getAnswertext()) == 0) && (strlen($answer->getImage()) == 0)) return false;
105  }
106  return true;
107  }
108  else
109  {
110  return false;
111  }
112  }
113 
120  public function saveToDb($original_id = "")
121  {
123  global $ilDB;
124 
126 
127  // kann das weg?
128  $oldthumbsize = 0;
129  if ($this->isSingleline && ($this->getThumbSize()))
130  {
131  // get old thumbnail size
132  $result = $ilDB->queryF("SELECT thumb_size FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
133  array("integer"),
134  array($this->getId())
135  );
136  if ($result->numRows() == 1)
137  {
138  $data = $ilDB->fetchAssoc($result);
139  $oldthumbsize = $data['thumb_size'];
140  }
141  }
142 
143 
145 
147 
148  parent::saveToDb($original_id);
149  }
150 
151  /*
152  * Rebuild the thumbnail images with a new thumbnail size
153  */
154  protected function rebuildThumbnails()
155  {
156  if ($this->isSingleline && ($this->getThumbSize()))
157  {
158  foreach ($this->getAnswers() as $answer)
159  {
160  if (strlen($answer->getImage()))
161  {
162  $this->generateThumbForFile($this->getImagePath(), $answer->getImage());
163  }
164  }
165  }
166  }
167 
168  public function getThumbPrefix()
169  {
170  return "thumb.";
171  }
172 
173  protected function generateThumbForFile($path, $file)
174  {
175  $filename = $path . $file;
176  if (@file_exists($filename))
177  {
178  $thumbpath = $path . $this->getThumbPrefix() . $file;
179  $path_info = @pathinfo($filename);
180  $ext = "";
181  switch (strtoupper($path_info['extension']))
182  {
183  case 'PNG':
184  $ext = 'PNG';
185  break;
186  case 'GIF':
187  $ext = 'GIF';
188  break;
189  default:
190  $ext = 'JPEG';
191  break;
192  }
193  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbSize());
194  }
195  }
196 
204  function loadFromDb($question_id)
205  {
206  global $ilDB;
207 
208  $hasimages = 0;
209 
210  $result = $ilDB->queryF("SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
211  array("integer"),
212  array($question_id)
213  );
214  if ($result->numRows() == 1)
215  {
216  $data = $ilDB->fetchAssoc($result);
217  $this->setId($question_id);
218  $this->setObjId($data["obj_fi"]);
219  $this->setTitle($data["title"]);
220  $this->setNrOfTries($data['nr_of_tries']);
221  $this->setComment($data["description"]);
222  $this->setOriginalId($data["original_id"]);
223  $this->setAuthor($data["author"]);
224  $this->setPoints($data["points"]);
225  $this->setOwner($data["owner"]);
226  include_once("./Services/RTE/classes/class.ilRTE.php");
227  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
228  $shuffle = (is_null($data['shuffle'])) ? true : $data['shuffle'];
229  $this->setShuffle($shuffle);
230  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
231  $this->setThumbSize($data['thumb_size']);
232  $this->isSingleline = ($data['allow_images']) ? false : true;
233  $this->lastChange = $data['tstamp'];
234  $this->feedback_setting = $data['feedback_setting'];
235 
236  try
237  {
238  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
239  }
241  {
242  }
243  }
244 
245  $result = $ilDB->queryF("SELECT * FROM qpl_a_sc WHERE question_fi = %s ORDER BY aorder ASC",
246  array('integer'),
247  array($question_id)
248  );
249  include_once "./Modules/TestQuestionPool/classes/class.assAnswerBinaryStateImage.php";
250  if ($result->numRows() > 0)
251  {
252  while ($data = $ilDB->fetchAssoc($result))
253  {
254  $imagefilename = $this->getImagePath() . $data["imagefile"];
255  if (!@file_exists($imagefilename))
256  {
257  $data["imagefile"] = "";
258  }
259  include_once("./Services/RTE/classes/class.ilRTE.php");
260  $data["answertext"] = ilRTE::_replaceMediaObjectImageSrc($data["answertext"], 1);
261  array_push($this->answers, new ASS_AnswerBinaryStateImage($data["answertext"], $data["points"], $data["aorder"], 1, $data["imagefile"]));
262  }
263  }
264 
265  parent::loadFromDb($question_id);
266  }
267 
273  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
274  {
275  if ($this->id <= 0)
276  {
277  // The question has not been saved. It cannot be duplicated
278  return;
279  }
280  // duplicate the question in database
281  $this_id = $this->getId();
282  $thisObjId = $this->getObjId();
283 
284  $clone = $this;
285  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
287  $clone->id = -1;
288 
289  if( (int)$testObjId > 0 )
290  {
291  $clone->setObjId($testObjId);
292  }
293 
294  if ($title)
295  {
296  $clone->setTitle($title);
297  }
298 
299  if ($author)
300  {
301  $clone->setAuthor($author);
302  }
303  if ($owner)
304  {
305  $clone->setOwner($owner);
306  }
307  if ($for_test)
308  {
309  $clone->saveToDb($original_id);
310  }
311  else
312  {
313  $clone->saveToDb();
314  }
315 
316  // copy question page content
317  $clone->copyPageOfQuestion($this_id);
318 
319  // copy XHTML media objects
320  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
321  // duplicate the images
322  $clone->duplicateImages($this_id, $thisObjId);
323 
324  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
325 
326  return $clone->id;
327  }
328 
334  function copyObject($target_questionpool_id, $title = "")
335  {
336  if ($this->id <= 0)
337  {
338  // The question has not been saved. It cannot be duplicated
339  return;
340  }
341  // duplicate the question in database
342  $clone = $this;
343  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
345  $clone->id = -1;
346  $source_questionpool_id = $this->getObjId();
347  $clone->setObjId($target_questionpool_id);
348  if ($title)
349  {
350  $clone->setTitle($title);
351  }
352  $clone->saveToDb();
353  // copy question page content
354  $clone->copyPageOfQuestion($original_id);
355  // copy XHTML media objects
356  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
357  // duplicate the image
358  $clone->copyImages($original_id, $source_questionpool_id);
359 
360  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
361 
362  return $clone->id;
363  }
364 
365  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
366  {
367  if ($this->id <= 0)
368  {
369  // The question has not been saved. It cannot be duplicated
370  return;
371  }
372 
373  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
374 
375  $sourceQuestionId = $this->id;
376  $sourceParentId = $this->getObjId();
377 
378  // duplicate the question in database
379  $clone = $this;
380  $clone->id = -1;
381 
382  $clone->setObjId($targetParentId);
383 
384  if ($targetQuestionTitle)
385  {
386  $clone->setTitle($targetQuestionTitle);
387  }
388 
389  $clone->saveToDb();
390  // copy question page content
391  $clone->copyPageOfQuestion($sourceQuestionId);
392  // copy XHTML media objects
393  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
394  // duplicate the image
395  $clone->copyImages($sourceQuestionId, $sourceParentId);
396 
397  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
398 
399  return $clone->id;
400  }
401 
409  function getOutputType()
410  {
411  return $this->output_type;
412  }
413 
421  function setOutputType($output_type = OUTPUT_ORDER)
422  {
423  $this->output_type = $output_type;
424  }
425 
439  function addAnswer(
440  $answertext = "",
441  $points = 0.0,
442  $order = 0,
443  $answerimage = ""
444  )
445  {
446  include_once "./Modules/TestQuestionPool/classes/class.assAnswerBinaryStateImage.php";
447  if (array_key_exists($order, $this->answers))
448  {
449  // insert answer
450  $answer = new ASS_AnswerBinaryStateImage($answertext, $points, $order, 1, $answerimage);
451  $newchoices = array();
452  for ($i = 0; $i < $order; $i++)
453  {
454  array_push($newchoices, $this->answers[$i]);
455  }
456  array_push($newchoices, $answer);
457  for ($i = $order; $i < count($this->answers); $i++)
458  {
459  $changed = $this->answers[$i];
460  $changed->setOrder($i+1);
461  array_push($newchoices, $changed);
462  }
463  $this->answers = $newchoices;
464  }
465  else
466  {
467  // add answer
468  $answer = new ASS_AnswerBinaryStateImage($answertext, $points, count($this->answers), 1, $answerimage);
469  array_push($this->answers, $answer);
470  }
471  }
472 
480  function getAnswerCount()
481  {
482  return count($this->answers);
483  }
484 
494  function getAnswer($index = 0)
495  {
496  if ($index < 0) return NULL;
497  if (count($this->answers) < 1) return NULL;
498  if ($index >= count($this->answers)) return NULL;
499 
500  return $this->answers[$index];
501  }
502 
511  function deleteAnswer($index = 0)
512  {
513  if ($index < 0) return;
514  if (count($this->answers) < 1) return;
515  if ($index >= count($this->answers)) return;
516  $answer = $this->answers[$index];
517  if (strlen($answer->getImage())) $this->deleteImage($answer->getImage());
518  unset($this->answers[$index]);
519  $this->answers = array_values($this->answers);
520  for ($i = 0; $i < count($this->answers); $i++)
521  {
522  if ($this->answers[$i]->getOrder() > $index)
523  {
524  $this->answers[$i]->setOrder($i);
525  }
526  }
527  }
528 
535  function flushAnswers()
536  {
537  $this->answers = array();
538  }
539 
546  function getMaximumPoints()
547  {
548  $points = 0;
549  foreach ($this->answers as $key => $value)
550  {
551  if ($value->getPoints() > $points)
552  {
553  $points = $value->getPoints();
554  }
555  }
556  return $points;
557  }
558 
569  public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
570  {
571  if( $returndetails )
572  {
573  throw new ilTestException('return details not implemented for '.__METHOD__);
574  }
575 
576  global $ilDB;
577 
578  $found_values = array();
579  if (is_null($pass))
580  {
581  $pass = $this->getSolutionMaxPass($active_id);
582  }
583  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
584  while ($data = $ilDB->fetchAssoc($result))
585  {
586  if (strcmp($data["value1"], "") != 0)
587  {
588  array_push($found_values, $data["value1"]);
589  }
590  }
591  $points = 0;
592  foreach ($this->answers as $key => $answer)
593  {
594  if (count($found_values) > 0)
595  {
596  if (in_array($key, $found_values))
597  {
598  $points += $answer->getPoints();
599  }
600  }
601  }
602 
603  return $points;
604  }
605 
607  {
608  $participantSolution = $previewSession->getParticipantsSolution();
609  foreach ($this->answers as $key => $answer)
610  {
611  if( is_numeric($participantSolution) && $key == $participantSolution )
612  {
613  return $answer->getPoints();
614  }
615  }
616 
617  return 0;
618  }
619 
628  public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
629  {
630  global $ilDB;
631  global $ilUser;
632 
633  if (is_null($pass))
634  {
635  include_once "./Modules/Test/classes/class.ilObjTest.php";
636  $pass = ilObjTest::_getPass($active_id);
637  }
638  $entered_values = 0;
639 
640  $this->getProcessLocker()->requestUserSolutionUpdateLock();
641 
642  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorized);
643  $row = $ilDB->fetchAssoc($result);
644  $update = $row["solution_id"];
645 
646  if ($update)
647  {
648  if (strlen($_POST["multiple_choice_result"]))
649  {
650  $this->updateCurrentSolution($update, $_POST["multiple_choice_result"], null, $authorized);
651  $entered_values++;
652  }
653  else
654  {
655  $this->removeSolutionRecordById($update);
656  }
657  }
658  else
659  {
660  if (strlen($_POST["multiple_choice_result"]))
661  {
662  $this->saveCurrentSolution($active_id, $pass, $_POST['multiple_choice_result'], null, $authorized);
663  $entered_values++;
664  }
665  }
666 
667  $this->getProcessLocker()->releaseUserSolutionUpdateLock();
668 
669  if ($entered_values)
670  {
671  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
673  {
674  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
675  }
676  }
677  else
678  {
679  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
681  {
682  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
683  }
684  }
685 
686  return true;
687  }
688 
689  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
690  {
691  if( strlen($_POST['multiple_choice_result'.$this->getId().'ID']) )
692  {
693  $previewSession->setParticipantsSolution($_POST['multiple_choice_result'.$this->getId().'ID']);
694  }
695  else
696  {
697  $previewSession->setParticipantsSolution(null);
698  }
699  }
700 
701  public function saveAdditionalQuestionDataToDb()
702  {
704  global $ilDB;
705 
706  // save additional data
707  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
708  array( "integer" ),
709  array( $this->getId() )
710  );
711 
712  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName(
713  ) . " (question_fi, shuffle, allow_images, thumb_size) VALUES (%s, %s, %s, %s)",
714  array( "integer", "text", "text", "integer" ),
715  array(
716  $this->getId(),
717  $this->getShuffle(),
718  ($this->isSingleline) ? "0" : "1",
719  (strlen( $this->getThumbSize() ) == 0) ? null : $this->getThumbSize()
720  )
721  );
722  }
723 
724  public function saveAnswerSpecificDataToDb()
725  {
727  global $ilDB;
728  if (!$this->isSingleline)
729  {
730  ilUtil::delDir( $this->getImagePath() );
731  }
732  $ilDB->manipulateF( "DELETE FROM qpl_a_sc WHERE question_fi = %s",
733  array( 'integer' ),
734  array( $this->getId() )
735  );
736 
737  foreach ($this->answers as $key => $value)
738  {
740  $answer_obj = $this->answers[$key];
741  $next_id = $ilDB->nextId( 'qpl_a_sc' );
742  $ilDB->manipulateF( "INSERT INTO qpl_a_sc (answer_id, question_fi, answertext, points, aorder, imagefile, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
743  array( 'integer', 'integer', 'text', 'float', 'integer', 'text', 'integer' ),
744  array(
745  $next_id,
746  $this->getId(),
747  ilRTE::_replaceMediaObjectImageSrc( $answer_obj->getAnswertext(), 0 ),
748  $answer_obj->getPoints(),
749  $answer_obj->getOrder(),
750  $answer_obj->getImage(),
751  time()
752  )
753  );
754  }
755  $this->rebuildThumbnails();
756  }
757 
766  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
767  {
768  // nothing to rework!
769  }
770 
777  function getQuestionType()
778  {
779  return "assSingleChoice";
780  }
781 
789  {
790  return "qpl_qst_sc";
791  }
792 
800  {
801  return "qpl_a_sc";
802  }
803 
812  function setImageFile($image_filename, $image_tempfilename = "")
813  {
814  $result = 0;
815  if (!empty($image_tempfilename))
816  {
817  $image_filename = str_replace(" ", "_", $image_filename);
818  $imagepath = $this->getImagePath();
819  if (!file_exists($imagepath))
820  {
821  ilUtil::makeDirParents($imagepath);
822  }
823  //if (!move_uploaded_file($image_tempfilename, $imagepath . $image_filename))
824  if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
825  {
826  $result = 2;
827  }
828  else
829  {
830  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
831  $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
832  if (!preg_match("/^image/", $mimetype))
833  {
834  unlink($imagepath . $image_filename);
835  $result = 1;
836  }
837  else
838  {
839  // create thumbnail file
840  if ($this->isSingleline && ($this->getThumbSize()))
841  {
842  $this->generateThumbForFile($imagepath, $image_filename);
843  }
844  }
845  }
846  }
847  return $result;
848  }
849 
856  function deleteImage($image_filename)
857  {
858  $imagepath = $this->getImagePath();
859  @unlink($imagepath . $image_filename);
860  $thumbpath = $imagepath . $this->getThumbPrefix() . $image_filename;
861  @unlink($thumbpath);
862  }
863 
864  function duplicateImages($question_id, $objectId = null)
865  {
866  global $ilLog;
867  $imagepath = $this->getImagePath();
868  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
869 
870  if( (int)$objectId > 0 )
871  {
872  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
873  }
874 
875  foreach ($this->answers as $answer)
876  {
877  $filename = $answer->getImage();
878  if (strlen($filename))
879  {
880  if (!file_exists($imagepath))
881  {
882  ilUtil::makeDirParents($imagepath);
883  }
884  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
885  {
886  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
887  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
888  }
889  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
890  {
891  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
892  {
893  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
894  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
895  }
896  }
897  }
898  }
899  }
900 
901  function copyImages($question_id, $source_questionpool)
902  {
904  global $ilLog;
905 
906  $imagepath = $this->getImagePath();
907  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
908  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
909  foreach ($this->answers as $answer)
910  {
911  $filename = $answer->getImage();
912  if (strlen($filename))
913  {
914  if (!file_exists($imagepath))
915  {
916  ilUtil::makeDirParents($imagepath);
917  }
918  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
919  {
920  $ilLog->warning(sprintf(
921  "Could not clone source image '%s' to '%s' (srcQuestionId: %s|tgtQuestionId: %s|srcParentObjId: %s|tgtParentObjId: %s)",
922  $imagepath_original . $filename, $imagepath . $filename,
923  $question_id, $this->id, $source_questionpool, $this->obj_id
924  ));
925  }
926  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
927  {
928  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
929  {
930  $ilLog->warning(sprintf(
931  "Could not clone thumbnail source image '%s' to '%s' (srcQuestionId: %s|tgtQuestionId: %s|srcParentObjId: %s|tgtParentObjId: %s)",
932  $imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename,
933  $question_id, $this->id, $source_questionpool, $this->obj_id
934  ));
935  }
936  }
937  }
938  }
939  }
940 
944  protected function syncImages()
945  {
946  global $ilLog;
947  $question_id = $this->getOriginalId();
948  $imagepath = $this->getImagePath();
949  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
950  ilUtil::delDir($imagepath_original);
951  foreach ($this->answers as $answer)
952  {
953  $filename = $answer->getImage();
954  if (strlen($filename))
955  {
956  if (@file_exists($imagepath . $filename))
957  {
958  if (!file_exists($imagepath))
959  {
960  ilUtil::makeDirParents($imagepath);
961  }
962  if (!file_exists($imagepath_original))
963  {
964  ilUtil::makeDirParents($imagepath_original);
965  }
966  if (!@copy($imagepath . $filename, $imagepath_original . $filename))
967  {
968  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
969  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
970  }
971  }
972  if (@file_exists($imagepath . $this->getThumbPrefix() . $filename))
973  {
974  if (!@copy($imagepath . $this->getThumbPrefix() . $filename, $imagepath_original . $this->getThumbPrefix() . $filename))
975  {
976  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
977  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
978  }
979  }
980  }
981  }
982  }
983 
989  {
990  $text = parent::getRTETextWithMediaObjects();
991  foreach ($this->answers as $index => $answer)
992  {
993  $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), $index);
994  $answer_obj = $this->answers[$index];
995  $text .= $answer_obj->getAnswertext();
996  }
997  return $text;
998  }
999 
1003  function &getAnswers()
1004  {
1005  return $this->answers;
1006  }
1007 
1020  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
1021  {
1022  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1023  $solution = $this->getSolutionValues($active_id, $pass);
1024  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
1025  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
1026  $i = 1;
1027  foreach ($this->getAnswers() as $id => $answer)
1028  {
1029  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($answer->getAnswertext()), $format_bold);
1030  if(
1031  count($solution) > 0 &&
1032  isset($solution[0]) &&
1033  is_array($solution[0]) &&
1034  strlen($solution[0]['value1']) > 0 && $id == $solution[0]['value1'])
1035  {
1036  $worksheet->write($startrow + $i, 1, 1);
1037  }
1038  else
1039  {
1040  $worksheet->write($startrow + $i, 1, 0);
1041  }
1042  $i++;
1043  }
1044  return $startrow + $i + 1;
1045  }
1046 
1047  public function getThumbSize()
1048  {
1049  return $this->thumb_size;
1050  }
1051 
1052  public function setThumbSize($a_size)
1053  {
1054  $this->thumb_size = $a_size;
1055  }
1056 
1061  {
1062  foreach($this->getAnswers() as $answer)
1063  {
1064  /* @var ASS_AnswerBinaryStateImage $answer */
1065  $answer->setAnswertext( $migrator->migrateToLmContent($answer->getAnswertext()) );
1066  }
1067  }
1068 
1072  public function toJSON()
1073  {
1074  include_once("./Services/RTE/classes/class.ilRTE.php");
1075  $result = array();
1076  $result['id'] = (int) $this->getId();
1077  $result['type'] = (string) $this->getQuestionType();
1078  $result['title'] = (string) $this->getTitle();
1079  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1080  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1081  $result['shuffle'] = (bool) $this->getShuffle();
1082 
1083  $result['feedback'] = array(
1084  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1085  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1086  );
1087 
1088  $answers = array();
1089  $has_image = false;
1090  foreach ($this->getAnswers() as $key => $answer_obj)
1091  {
1092  if((string) $answer_obj->getImage())
1093  {
1094  $has_image = true;
1095  }
1096  array_push($answers, array(
1097  "answertext" => (string) $this->formatSAQuestion($answer_obj->getAnswertext()),
1098  "points" => (float)$answer_obj->getPoints(),
1099  "order" => (int)$answer_obj->getOrder(),
1100  "image" => (string) $answer_obj->getImage(),
1101  "feedback" => $this->formatSAQuestion(
1102  $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), $key)
1103  )
1104  ));
1105  }
1106  $result['answers'] = $answers;
1107  if($has_image)
1108  {
1109  $result['path'] = $this->getImagePathWeb();
1110  $result['thumb'] = $this->getThumbSize();
1111  }
1112 
1113  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1114  $result['mobs'] = $mobs;
1115 
1116  return json_encode($result);
1117  }
1118 
1119  public function removeAnswerImage($index)
1120  {
1121  $answer = $this->answers[$index];
1122  if (is_object($answer))
1123  {
1124  $this->deleteImage($answer->getImage());
1125  $answer->setImage('');
1126  }
1127  }
1128 
1129  function createRandomSolution($active_id, $pass)
1130  {
1131  $value = rand(0, count($this->answers)-1);
1132  $_POST["multiple_choice_result"] = (strlen($value)) ? (string)$value : '0';
1133  $this->saveWorkingData($active_id, $pass);
1134  $this->calculateResultsFromSolution($active_id, $pass);
1135  }
1136 
1138  {
1139  global $ilUser;
1140 
1141  $multilineAnswerSetting = $ilUser->getPref("tst_multiline_answers");
1142  if ($multilineAnswerSetting != 1)
1143  {
1144  $multilineAnswerSetting = 0;
1145  }
1146  return $multilineAnswerSetting;
1147  }
1148 
1149  function setMultilineAnswerSetting($a_setting = 0)
1150  {
1151  global $ilUser;
1152  $ilUser->writePref("tst_multiline_answers", $a_setting);
1153  }
1154 
1164  public function setSpecificFeedbackSetting($a_feedback_setting)
1165  {
1166  $this->feedback_setting = $a_feedback_setting;
1167  }
1168 
1178  public function getSpecificFeedbackSetting()
1179  {
1180  if ($this->feedback_setting)
1181  {
1182  return $this->feedback_setting;
1183  }
1184  else
1185  {
1186  return 1;
1187  }
1188  }
1189 
1191  {
1192  return 'feedback_correct_sc_mc';
1193  }
1194 
1205  public function isAnswered($active_id, $pass = NULL)
1206  {
1207  $numExistingSolutionRecords = assQuestion::getNumExistingSolutionRecords($active_id, $pass, $this->getId());
1208 
1209  return $numExistingSolutionRecords > 0;
1210  }
1211 
1222  public static function isObligationPossible($questionId)
1223  {
1224  return true;
1225  }
1226 
1235  public function getOperators($expression)
1236  {
1237  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1239  }
1240 
1245  public function getExpressionTypes()
1246  {
1247  return array(
1251  );
1252  }
1253 
1262  public function getUserQuestionResult($active_id, $pass)
1263  {
1265  global $ilDB;
1266  $result = new ilUserQuestionResult($this, $active_id, $pass);
1267 
1268  $maxStep = $this->lookupMaxStep($active_id, $pass);
1269 
1270  if( $maxStep !== null )
1271  {
1272  $data = $ilDB->queryF(
1273  "SELECT * FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1274  array("integer", "integer", "integer","integer"),
1275  array($active_id, $pass, $this->getId(), $maxStep)
1276  );
1277  }
1278  else
1279  {
1280  $data = $ilDB->queryF(
1281  "SELECT * FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1282  array("integer", "integer", "integer"),
1283  array($active_id, $pass, $this->getId())
1284  );
1285  }
1286 
1287  $row = $ilDB->fetchAssoc($data);
1288 
1289  if($row != null)
1290  {
1291  ++$row["value1"];
1292  $result->addKeyValue($row["value1"], $row["value1"]);
1293  }
1294 
1295  $points = $this->calculateReachedPoints($active_id, $pass);
1296  $max_points = $this->getMaximumPoints();
1297 
1298  $result->setReachedPercentage(($points/$max_points) * 100);
1299 
1300  return $result;
1301  }
1302 
1311  public function getAvailableAnswerOptions($index = null)
1312  {
1313  if($index !== null)
1314  {
1315  return $this->getAnswer($index);
1316  }
1317  else
1318  {
1319  return $this->getAnswers();
1320  }
1321  }
1322 
1326  protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1327  {
1328  parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1329 
1330  $origImagePath = $this->buildImagePath($origQuestionId, $origParentObjId);
1331  $dupImagePath = $this->buildImagePath($dupQuestionId, $dupParentObjId);
1332 
1333  ilUtil::delDir($origImagePath);
1334  if(is_dir($dupImagePath))
1335  {
1336  ilUtil::makeDirParents($origImagePath);
1337  ilUtil::rCopy($dupImagePath, $origImagePath);
1338  }
1339  }
1340 }
static makeDirParents($a_dir)
Create a new directory and all parent directories.
getOutputType()
Gets the single choice output type which is either OUTPUT_ORDER (=0) or OUTPUT_RANDOM (=1)...
getId()
Gets the id of the assQuestion object.
saveToDb($original_id="")
Saves the question to the database.
print $file
generateThumbForFile($path, $file)
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
Class iQuestionCondition.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
$_POST['username']
Definition: cron.php:12
static getNumExistingSolutionRecords($activeId, $pass, $questionId)
returns the number of existing solution records for the given test active / pass and given question i...
$result
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
Abstract basic class which is to be extended by the concrete assessment question type classes...
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
Class for answers with a binary state indicator.
_convert_text($a_text, $a_target="has been removed")
setOutputType($output_type=OUTPUT_ORDER)
Sets the output type of the assSingleChoice object.
setMultilineAnswerSetting($a_setting=0)
& getAnswers()
Returns a reference to the answers array.
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
{}
getAnswerCount()
Returns the number of answers.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
isComplete()
Returns true, if a single choice question is complete for use.
setId($id=-1)
Sets the id of the assQuestion object.
copyObject($target_questionpool_id, $title="")
Copies an assSingleChoice object.
getQuestionType()
Returns the question type of the question.
getAnswerTableName()
Returns the name of the answer table in the database.
getImagePathWeb()
Returns the web image path for web accessable images of a question.
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. ...
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
loadFromDb($question_id)
Loads a assSingleChoice object from a database.
calculateResultsFromSolution($active_id, $pass=NULL, $obligationsEnabled=false)
Calculates the question results from a previously saved question solution.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setNrOfTries($a_nr_of_tries)
setSpecificFeedbackSetting($a_feedback_setting)
Sets the feedback settings in effect for the question.
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assSingleChoiceQuestion.
getAnswer($index=0)
Returns an answer with a given index.
setShuffle($shuffle=true)
Sets the shuffle flag.
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...
getOperators($expression)
Get all available operations for a specific question.
getObjId()
Get the object id of the container object.
getShuffle()
Gets the shuffle flag.
Base Exception for all Exceptions relating to Modules/Test.
getSpecificFeedbackSetting()
Gets the current feedback settings in effect for the question.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
isAnswered($active_id, $pass=NULL)
returns boolean wether the question is answered during test pass or not
removeSolutionRecordById($solutionId)
deleteImage($image_filename)
Deletes an image file.
setAuthor($author="")
Sets the authors name of the assQuestion object.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
$data
$mobs
Class ilUserQuestionResult.
createRandomSolution($active_id, $pass)
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
Class for single choice questions.
deleteAnswer($index=0)
Deletes an answer with a given index.
Interface ilObjAnswerScoringAdjustable.
toJSON()
Returns a JSON representation of the question.
addAnswer( $answertext="", $points=0.0, $order=0, $answerimage="")
Adds a possible answer for a single choice question.
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $output_type=OUTPUT_ORDER)
assSingleChoice constructor
getQuestion()
Gets the question string of the question object.
syncImages()
Sync images of a MC question on synchronisation with the original question.
flushAnswers()
Deletes all answers.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
updateCurrentSolution($solutionId, $value1, $value2, $authorized=true)
getAdditionalTableName()
Returns the name of the additional question data table in the database.
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
_getLogLanguage()
retrieve the log language for assessment logging
$filename
Definition: buildRTE.php:89
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
_getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
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 getMimeType($a_file, $a_external=false)
get mime type for file
global $ilUser
Definition: imgupload.php:15
setImageFile($image_filename, $image_tempfilename="")
Sets the image file and uploads the image to the object&#39;s image directory.
setQuestion($question="")
Sets the question string of the question object.
static convertImage($a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
duplicateImages($question_id, $objectId=null)
Interface ilObjQuestionScoringAdjustable.
$path
Definition: index.php:22
buildImagePath($questionId, $parentObjectId)
global $ilDB
setOriginalId($original_id)
getExpressionTypes()
Get all available expression types for a specific question.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
$text
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getTitle()
Gets the title string of the assQuestion object.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
const OUTPUT_ORDER
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
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
setComment($comment="")
Sets the comment string of the assQuestion object.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.