ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
25 {
33  var $answers;
34 
44 
50  protected $thumb_size;
51 
58  protected $feedback_setting;
59 
74  public function __construct(
75  $title = "",
76  $comment = "",
77  $author = "",
78  $owner = -1,
79  $question = "",
81  )
82  {
84  $this->thumb_size = 150;
85  $this->output_type = $output_type;
86  $this->answers = array();
87  $this->shuffle = 1;
88  $this->feedback_setting = 2;
89  }
90 
97  function isComplete()
98  {
99  if (strlen($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
100  {
101  foreach ($this->answers as $answer)
102  {
103  if ((strlen($answer->getAnswertext()) == 0) && (strlen($answer->getImage()) == 0)) return false;
104  }
105  return true;
106  }
107  else
108  {
109  return false;
110  }
111  }
112 
119  public function saveToDb($original_id = "")
120  {
122  global $ilDB;
123 
125 
126  // kann das weg?
127  $oldthumbsize = 0;
128  if ($this->isSingleline && ($this->getThumbSize()))
129  {
130  // get old thumbnail size
131  $result = $ilDB->queryF("SELECT thumb_size FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
132  array("integer"),
133  array($this->getId())
134  );
135  if ($result->numRows() == 1)
136  {
137  $data = $ilDB->fetchAssoc($result);
138  $oldthumbsize = $data['thumb_size'];
139  }
140  }
141 
142 
144 
146 
148  }
149 
150  /*
151  * Rebuild the thumbnail images with a new thumbnail size
152  */
153  protected function rebuildThumbnails()
154  {
155  if ($this->isSingleline && ($this->getThumbSize()))
156  {
157  foreach ($this->getAnswers() as $answer)
158  {
159  if (strlen($answer->getImage()))
160  {
161  $this->generateThumbForFile($this->getImagePath(), $answer->getImage());
162  }
163  }
164  }
165  }
166 
167  public function getThumbPrefix()
168  {
169  return "thumb.";
170  }
171 
172  protected function generateThumbForFile($path, $file)
173  {
174  $filename = $path . $file;
175  if (@file_exists($filename))
176  {
177  $thumbpath = $path . $this->getThumbPrefix() . $file;
178  $path_info = @pathinfo($filename);
179  $ext = "";
180  switch (strtoupper($path_info['extension']))
181  {
182  case 'PNG':
183  $ext = 'PNG';
184  break;
185  case 'GIF':
186  $ext = 'GIF';
187  break;
188  default:
189  $ext = 'JPEG';
190  break;
191  }
192  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbSize());
193  }
194  }
195 
203  function loadFromDb($question_id)
204  {
205  global $ilDB;
206 
207  $hasimages = 0;
208 
209  $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",
210  array("integer"),
211  array($question_id)
212  );
213  if ($result->numRows() == 1)
214  {
215  $data = $ilDB->fetchAssoc($result);
216  $this->setId($question_id);
217  $this->setObjId($data["obj_fi"]);
218  $this->setTitle($data["title"]);
219  $this->setNrOfTries($data['nr_of_tries']);
220  $this->setComment($data["description"]);
221  $this->setOriginalId($data["original_id"]);
222  $this->setAuthor($data["author"]);
223  $this->setPoints($data["points"]);
224  $this->setOwner($data["owner"]);
225  include_once("./Services/RTE/classes/class.ilRTE.php");
226  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
227  $shuffle = (is_null($data['shuffle'])) ? true : $data['shuffle'];
228  $this->setShuffle($shuffle);
229  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
230  $this->setThumbSize($data['thumb_size']);
231  $this->isSingleline = ($data['allow_images']) ? false : true;
232  $this->lastChange = $data['tstamp'];
233  $this->feedback_setting = $data['feedback_setting'];
234 
235  try
236  {
237  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
238  }
240  {
241  }
242  }
243 
244  $result = $ilDB->queryF("SELECT * FROM qpl_a_sc WHERE question_fi = %s ORDER BY aorder ASC",
245  array('integer'),
246  array($question_id)
247  );
248  include_once "./Modules/TestQuestionPool/classes/class.assAnswerBinaryStateImage.php";
249  if ($result->numRows() > 0)
250  {
251  while ($data = $ilDB->fetchAssoc($result))
252  {
253  $imagefilename = $this->getImagePath() . $data["imagefile"];
254  if (!@file_exists($imagefilename))
255  {
256  $data["imagefile"] = "";
257  }
258  include_once("./Services/RTE/classes/class.ilRTE.php");
259  $data["answertext"] = ilRTE::_replaceMediaObjectImageSrc($data["answertext"], 1);
260  array_push($this->answers, new ASS_AnswerBinaryStateImage($data["answertext"], $data["points"], $data["aorder"], 1, $data["imagefile"]));
261  }
262  }
263 
264  parent::loadFromDb($question_id);
265  }
266 
272  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
273  {
274  if ($this->id <= 0)
275  {
276  // The question has not been saved. It cannot be duplicated
277  return;
278  }
279  // duplicate the question in database
280  $this_id = $this->getId();
281  $thisObjId = $this->getObjId();
282 
283  $clone = $this;
284  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
286  $clone->id = -1;
287 
288  if( (int)$testObjId > 0 )
289  {
290  $clone->setObjId($testObjId);
291  }
292 
293  if ($title)
294  {
295  $clone->setTitle($title);
296  }
297 
298  if ($author)
299  {
300  $clone->setAuthor($author);
301  }
302  if ($owner)
303  {
304  $clone->setOwner($owner);
305  }
306  if ($for_test)
307  {
308  $clone->saveToDb($original_id);
309  }
310  else
311  {
312  $clone->saveToDb();
313  }
314 
315  // copy question page content
316  $clone->copyPageOfQuestion($this_id);
317 
318  // copy XHTML media objects
319  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
320  // duplicate the images
321  $clone->duplicateImages($this_id, $thisObjId);
322 
323  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
324 
325  return $clone->id;
326  }
327 
333  function copyObject($target_questionpool_id, $title = "")
334  {
335  if ($this->id <= 0)
336  {
337  // The question has not been saved. It cannot be duplicated
338  return;
339  }
340  // duplicate the question in database
341  $clone = $this;
342  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
344  $clone->id = -1;
345  $source_questionpool_id = $this->getObjId();
346  $clone->setObjId($target_questionpool_id);
347  if ($title)
348  {
349  $clone->setTitle($title);
350  }
351  $clone->saveToDb();
352  // copy question page content
353  $clone->copyPageOfQuestion($original_id);
354  // copy XHTML media objects
355  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
356  // duplicate the image
357  $clone->copyImages($original_id, $source_questionpool_id);
358 
359  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
360 
361  return $clone->id;
362  }
363 
364  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
365  {
366  if ($this->id <= 0)
367  {
368  // The question has not been saved. It cannot be duplicated
369  return;
370  }
371 
372  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
373 
374  $sourceQuestionId = $this->id;
375  $sourceParentId = $this->getObjId();
376 
377  // duplicate the question in database
378  $clone = $this;
379  $clone->id = -1;
380 
381  $clone->setObjId($targetParentId);
382 
383  if ($targetQuestionTitle)
384  {
385  $clone->setTitle($targetQuestionTitle);
386  }
387 
388  $clone->saveToDb();
389  // copy question page content
390  $clone->copyPageOfQuestion($sourceQuestionId);
391  // copy XHTML media objects
392  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
393  // duplicate the image
394  $clone->copyImages($sourceQuestionId, $sourceParentId);
395 
396  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
397 
398  return $clone->id;
399  }
400 
408  function getOutputType()
409  {
410  return $this->output_type;
411  }
412 
421  {
422  $this->output_type = $output_type;
423  }
424 
438  function addAnswer(
439  $answertext = "",
440  $points = 0.0,
441  $order = 0,
442  $answerimage = ""
443  )
444  {
445  include_once "./Modules/TestQuestionPool/classes/class.assAnswerBinaryStateImage.php";
446  if (array_key_exists($order, $this->answers))
447  {
448  // insert answer
449  $answer = new ASS_AnswerBinaryStateImage($answertext, $points, $order, 1, $answerimage);
450  $newchoices = array();
451  for ($i = 0; $i < $order; $i++)
452  {
453  array_push($newchoices, $this->answers[$i]);
454  }
455  array_push($newchoices, $answer);
456  for ($i = $order; $i < count($this->answers); $i++)
457  {
458  $changed = $this->answers[$i];
459  $changed->setOrder($i+1);
460  array_push($newchoices, $changed);
461  }
462  $this->answers = $newchoices;
463  }
464  else
465  {
466  // add answer
467  $answer = new ASS_AnswerBinaryStateImage($answertext, $points, count($this->answers), 1, $answerimage);
468  array_push($this->answers, $answer);
469  }
470  }
471 
479  function getAnswerCount()
480  {
481  return count($this->answers);
482  }
483 
493  function getAnswer($index = 0)
494  {
495  if ($index < 0) return NULL;
496  if (count($this->answers) < 1) return NULL;
497  if ($index >= count($this->answers)) return NULL;
498 
499  return $this->answers[$index];
500  }
501 
510  function deleteAnswer($index = 0)
511  {
512  if ($index < 0) return;
513  if (count($this->answers) < 1) return;
514  if ($index >= count($this->answers)) return;
515  $answer = $this->answers[$index];
516  if (strlen($answer->getImage())) $this->deleteImage($answer->getImage());
517  unset($this->answers[$index]);
518  $this->answers = array_values($this->answers);
519  for ($i = 0; $i < count($this->answers); $i++)
520  {
521  if ($this->answers[$i]->getOrder() > $index)
522  {
523  $this->answers[$i]->setOrder($i);
524  }
525  }
526  }
527 
534  function flushAnswers()
535  {
536  $this->answers = array();
537  }
538 
545  function getMaximumPoints()
546  {
547  $points = 0;
548  foreach ($this->answers as $key => $value)
549  {
550  if ($value->getPoints() > $points)
551  {
552  $points = $value->getPoints();
553  }
554  }
555  return $points;
556  }
557 
568  public function calculateReachedPoints($active_id, $pass = NULL, $returndetails = FALSE)
569  {
570  if( $returndetails )
571  {
572  throw new ilTestException('return details not implemented for '.__METHOD__);
573  }
574 
575  global $ilDB;
576 
577  $found_values = array();
578  if (is_null($pass))
579  {
580  $pass = $this->getSolutionMaxPass($active_id);
581  }
582  $result = $this->getCurrentSolutionResultSet($active_id, $pass);
583  while ($data = $ilDB->fetchAssoc($result))
584  {
585  if (strcmp($data["value1"], "") != 0)
586  {
587  array_push($found_values, $data["value1"]);
588  }
589  }
590  $points = 0;
591  foreach ($this->answers as $key => $answer)
592  {
593  if (count($found_values) > 0)
594  {
595  if (in_array($key, $found_values))
596  {
597  $points += $answer->getPoints();
598  }
599  }
600  }
601 
602  return $points;
603  }
604 
606  {
607  foreach ($this->answers as $key => $answer)
608  {
609  if( $key == $previewSession->getParticipantsSolution() )
610  {
611  return $answer->getPoints();
612  }
613  }
614 
615  return 0;
616  }
617 
626  public function saveWorkingData($active_id, $pass = NULL)
627  {
628  global $ilDB;
629  global $ilUser;
630 
631  if (is_null($pass))
632  {
633  include_once "./Modules/Test/classes/class.ilObjTest.php";
634  $pass = ilObjTest::_getPass($active_id);
635  }
636  $entered_values = 0;
637 
638  $this->getProcessLocker()->requestUserSolutionUpdateLock();
639 
640  $result = $this->getCurrentSolutionResultSet($active_id, $pass);
641  $row = $ilDB->fetchAssoc($result);
642  $update = $row["solution_id"];
643 
644  if ($update)
645  {
646  if (strlen($_POST["multiple_choice_result"]))
647  {
648  $affectedRows = $ilDB->update("tst_solutions", array(
649  "value1" => array("clob", $_POST["multiple_choice_result"]),
650  "tstamp" => array("integer", time())
651  ), array(
652  "solution_id" => array("integer", $update)
653  ));
654  $entered_values++;
655  }
656  else
657  {
658  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s",
659  array('integer'),
660  array($update)
661  );
662  }
663  }
664  else
665  {
666  if (strlen($_POST["multiple_choice_result"]))
667  {
668  $affectedRows = $this->saveCurrentSolution($active_id, $pass, $_POST['multiple_choice_result'], null);
669  $entered_values++;
670  }
671  }
672 
673  $this->getProcessLocker()->releaseUserSolutionUpdateLock();
674 
675  if ($entered_values)
676  {
677  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
679  {
680  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
681  }
682  }
683  else
684  {
685  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
687  {
688  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
689  }
690  }
691 
692  return true;
693  }
694 
695  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
696  {
697  if( strlen($_POST['multiple_choice_result'.$this->getId().'ID']) )
698  {
699  $previewSession->setParticipantsSolution($_POST['multiple_choice_result'.$this->getId().'ID']);
700  }
701  else
702  {
703  $previewSession->setParticipantsSolution(null);
704  }
705  }
706 
707  public function saveAdditionalQuestionDataToDb()
708  {
710  global $ilDB;
711 
712  // save additional data
713  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
714  array( "integer" ),
715  array( $this->getId() )
716  );
717 
718  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName(
719  ) . " (question_fi, shuffle, allow_images, thumb_size) VALUES (%s, %s, %s, %s)",
720  array( "integer", "text", "text", "integer" ),
721  array(
722  $this->getId(),
723  $this->getShuffle(),
724  ($this->isSingleline) ? "0" : "1",
725  (strlen( $this->getThumbSize() ) == 0) ? null : $this->getThumbSize()
726  )
727  );
728  }
729 
730  public function saveAnswerSpecificDataToDb()
731  {
733  global $ilDB;
734  if (!$this->isSingleline)
735  {
736  ilUtil::delDir( $this->getImagePath() );
737  }
738  $ilDB->manipulateF( "DELETE FROM qpl_a_sc WHERE question_fi = %s",
739  array( 'integer' ),
740  array( $this->getId() )
741  );
742 
743  foreach ($this->answers as $key => $value)
744  {
746  $answer_obj = $this->answers[$key];
747  $next_id = $ilDB->nextId( 'qpl_a_sc' );
748  $ilDB->manipulateF( "INSERT INTO qpl_a_sc (answer_id, question_fi, answertext, points, aorder, imagefile, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
749  array( 'integer', 'integer', 'text', 'float', 'integer', 'text', 'integer' ),
750  array(
751  $next_id,
752  $this->getId(),
753  ilRTE::_replaceMediaObjectImageSrc( $answer_obj->getAnswertext(), 0 ),
754  $answer_obj->getPoints(),
755  $answer_obj->getOrder(),
756  $answer_obj->getImage(),
757  time()
758  )
759  );
760  }
761  $this->rebuildThumbnails();
762  }
763 
772  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
773  {
774  // nothing to rework!
775  }
776 
777  function syncWithOriginal()
778  {
779  if ($this->getOriginalId())
780  {
781  $this->syncImages();
783  }
784  }
785 
792  function getQuestionType()
793  {
794  return "assSingleChoice";
795  }
796 
804  {
805  return "qpl_qst_sc";
806  }
807 
815  {
816  return "qpl_a_sc";
817  }
818 
827  function setImageFile($image_filename, $image_tempfilename = "")
828  {
829  $result = 0;
830  if (!empty($image_tempfilename))
831  {
832  $image_filename = str_replace(" ", "_", $image_filename);
833  $imagepath = $this->getImagePath();
834  if (!file_exists($imagepath))
835  {
836  ilUtil::makeDirParents($imagepath);
837  }
838  //if (!move_uploaded_file($image_tempfilename, $imagepath . $image_filename))
839  if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
840  {
841  $result = 2;
842  }
843  else
844  {
845  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
846  $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
847  if (!preg_match("/^image/", $mimetype))
848  {
849  unlink($imagepath . $image_filename);
850  $result = 1;
851  }
852  else
853  {
854  // create thumbnail file
855  if ($this->isSingleline && ($this->getThumbSize()))
856  {
857  $this->generateThumbForFile($imagepath, $image_filename);
858  }
859  }
860  }
861  }
862  return $result;
863  }
864 
871  function deleteImage($image_filename)
872  {
873  $imagepath = $this->getImagePath();
874  @unlink($imagepath . $image_filename);
875  $thumbpath = $imagepath . $this->getThumbPrefix() . $image_filename;
876  @unlink($thumbpath);
877  }
878 
879  function duplicateImages($question_id, $objectId = null)
880  {
881  global $ilLog;
882  $imagepath = $this->getImagePath();
883  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
884 
885  if( (int)$objectId > 0 )
886  {
887  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
888  }
889 
890  foreach ($this->answers as $answer)
891  {
892  $filename = $answer->getImage();
893  if (strlen($filename))
894  {
895  if (!file_exists($imagepath))
896  {
897  ilUtil::makeDirParents($imagepath);
898  }
899  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
900  {
901  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
902  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
903  }
904  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
905  {
906  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
907  {
908  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
909  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
910  }
911  }
912  }
913  }
914  }
915 
916  function copyImages($question_id, $source_questionpool)
917  {
918  global $ilLog;
919  $imagepath = $this->getImagePath();
920  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
921  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
922  foreach ($this->answers as $answer)
923  {
924  $filename = $answer->getImage();
925  if (strlen($filename))
926  {
927  if (!file_exists($imagepath))
928  {
929  ilUtil::makeDirParents($imagepath);
930  }
931  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
932  {
933  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
934  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
935  }
936  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
937  {
938  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
939  {
940  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
941  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
942  }
943  }
944  }
945  }
946  }
947 
951  protected function syncImages()
952  {
953  global $ilLog;
954  $question_id = $this->getOriginalId();
955  $imagepath = $this->getImagePath();
956  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
957  ilUtil::delDir($imagepath_original);
958  foreach ($this->answers as $answer)
959  {
960  $filename = $answer->getImage();
961  if (strlen($filename))
962  {
963  if (@file_exists($imagepath . $filename))
964  {
965  if (!file_exists($imagepath))
966  {
967  ilUtil::makeDirParents($imagepath);
968  }
969  if (!file_exists($imagepath_original))
970  {
971  ilUtil::makeDirParents($imagepath_original);
972  }
973  if (!@copy($imagepath . $filename, $imagepath_original . $filename))
974  {
975  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
976  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
977  }
978  }
979  if (@file_exists($imagepath . $this->getThumbPrefix() . $filename))
980  {
981  if (!@copy($imagepath . $this->getThumbPrefix() . $filename, $imagepath_original . $this->getThumbPrefix() . $filename))
982  {
983  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
984  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
985  }
986  }
987  }
988  }
989  }
990 
996  {
998  foreach ($this->answers as $index => $answer)
999  {
1000  $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), $index);
1001  $answer_obj = $this->answers[$index];
1002  $text .= $answer_obj->getAnswertext();
1003  }
1004  return $text;
1005  }
1006 
1010  function &getAnswers()
1011  {
1012  return $this->answers;
1013  }
1014 
1027  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
1028  {
1029  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1030  $solution = $this->getSolutionValues($active_id, $pass);
1031  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
1032  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
1033  $i = 1;
1034  foreach ($this->getAnswers() as $id => $answer)
1035  {
1036  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($answer->getAnswertext()), $format_bold);
1037  if ($id == $solution[0]["value1"])
1038  {
1039  $worksheet->write($startrow + $i, 1, 1);
1040  }
1041  else
1042  {
1043  $worksheet->write($startrow + $i, 1, 0);
1044  }
1045  $i++;
1046  }
1047  return $startrow + $i + 1;
1048  }
1049 
1050  public function getThumbSize()
1051  {
1052  return $this->thumb_size;
1053  }
1054 
1055  public function setThumbSize($a_size)
1056  {
1057  $this->thumb_size = $a_size;
1058  }
1059 
1063  public function toJSON()
1064  {
1065  include_once("./Services/RTE/classes/class.ilRTE.php");
1066  $result = array();
1067  $result['id'] = (int) $this->getId();
1068  $result['type'] = (string) $this->getQuestionType();
1069  $reilUtilsult['title'] = (string) $this->getTitle();
1070  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1071  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1072  $result['shuffle'] = (bool) $this->getShuffle();
1073 
1074  $result['feedback'] = array(
1075  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1076  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1077  );
1078 
1079  $answers = array();
1080  $has_image = false;
1081  foreach ($this->getAnswers() as $key => $answer_obj)
1082  {
1083  if((string) $answer_obj->getImage())
1084  {
1085  $has_image = true;
1086  }
1087  array_push($answers, array(
1088  "answertext" => (string) $this->formatSAQuestion($answer_obj->getAnswertext()),
1089  "points" => (float)$answer_obj->getPoints(),
1090  "order" => (int)$answer_obj->getOrder(),
1091  "image" => (string) $answer_obj->getImage(),
1092  "feedback" => ilRTE::_replaceMediaObjectImageSrc(
1093  $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), $key), 0
1094  )
1095  ));
1096  }
1097  $result['answers'] = $answers;
1098  if($has_image)
1099  {
1100  $result['path'] = $this->getImagePathWeb();
1101  $result['thumb'] = $this->getThumbSize();
1102  }
1103 
1104  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1105  $result['mobs'] = $mobs;
1106 
1107  return json_encode($result);
1108  }
1109 
1110  public function removeAnswerImage($index)
1111  {
1112  $answer = $this->answers[$index];
1113  if (is_object($answer))
1114  {
1115  $this->deleteImage($answer->getImage());
1116  $answer->setImage('');
1117  }
1118  }
1119 
1120  function createRandomSolution($active_id, $pass)
1121  {
1122  $value = rand(0, count($this->answers)-1);
1123  $_POST["multiple_choice_result"] = (strlen($value)) ? (string)$value : '0';
1124  $this->saveWorkingData($active_id, $pass);
1125  }
1126 
1128  {
1129  global $ilUser;
1130 
1131  $multilineAnswerSetting = $ilUser->getPref("tst_multiline_answers");
1132  if ($multilineAnswerSetting != 1)
1133  {
1134  $multilineAnswerSetting = 0;
1135  }
1136  return $multilineAnswerSetting;
1137  }
1138 
1139  function setMultilineAnswerSetting($a_setting = 0)
1140  {
1141  global $ilUser;
1142  $ilUser->writePref("tst_multiline_answers", $a_setting);
1143  }
1144 
1154  public function setSpecificFeedbackSetting($a_feedback_setting)
1155  {
1156  $this->feedback_setting = $a_feedback_setting;
1157  }
1158 
1168  public function getSpecificFeedbackSetting()
1169  {
1170  if ($this->feedback_setting)
1171  {
1172  return $this->feedback_setting;
1173  }
1174  else
1175  {
1176  return 1;
1177  }
1178  }
1179 
1190  public function isAnswered($active_id, $pass)
1191  {
1192  $numExistingSolutionRecords = assQuestion::getNumExistingSolutionRecords($active_id, $pass, $this->getId());
1193 
1194  return $numExistingSolutionRecords > 0;
1195  }
1196 
1207  public static function isObligationPossible($questionId)
1208  {
1209  return true;
1210  }
1211 
1220  public function getOperators($expression)
1221  {
1222  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1224  }
1225 
1230  public function getExpressionTypes()
1231  {
1232  return array(
1236  );
1237  }
1238 
1247  public function getUserQuestionResult($active_id, $pass)
1248  {
1250  global $ilDB;
1251  $result = new ilUserQuestionResult($this, $active_id, $pass);
1252 
1253  $data = $ilDB->queryF(
1254  "SELECT * FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = (
1255  SELECT MAX(step) FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s
1256  )",
1257  array("integer", "integer", "integer","integer", "integer", "integer"),
1258  array($active_id, $pass, $this->getId(), $active_id, $pass, $this->getId())
1259  );
1260 
1261  $row = $ilDB->fetchAssoc($data);
1262 
1263  if($row != null)
1264  {
1265  ++$row["value1"];
1266  $result->addKeyValue($row["value1"], $row["value1"]);
1267  }
1268 
1269  $points = $this->calculateReachedPoints($active_id, $pass);
1270  $max_points = $this->getMaximumPoints();
1271 
1272  $result->setReachedPercentage(($points/$max_points) * 100);
1273 
1274  return $result;
1275  }
1276 
1285  public function getAvailableAnswerOptions($index = null)
1286  {
1287  if($index !== null)
1288  {
1289  return $this->getAnswer($index);
1290  }
1291  else
1292  {
1293  return $this->getAnswers();
1294  }
1295  }
1296 }