ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assMultipleChoice.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 
25 {
33  var $answers;
34 
44 
45  public $isSingleline;
46  public $lastChange;
48 
50  protected $thumb_size;
51 
55  public function setIsSingleline($isSingleline)
56  {
57  $this->isSingleline = $isSingleline;
58  }
59 
63  public function getIsSingleline()
64  {
65  return $this->isSingleline;
66  }
67 
71  public function setLastChange($lastChange)
72  {
73  $this->lastChange = $lastChange;
74  }
75 
79  public function getLastChange()
80  {
81  return $this->lastChange;
82  }
83 
98  public function __construct(
99  $title = "",
100  $comment = "",
101  $author = "",
102  $owner = -1,
103  $question = "",
105  )
106  {
108  $this->output_type = $output_type;
109  $this->thumb_size = 150;
110  $this->answers = array();
111  $this->shuffle = 1;
112  }
113 
120  function isComplete()
121  {
122  if (strlen($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
123  {
124  return true;
125  }
126  else
127  {
128  return false;
129  }
130  }
131 
137  public function saveToDb($original_id = "")
138  {
142 
143  $this->ensureNoInvalidObligation($this->getId());
145  }
146 
150  protected function rebuildThumbnails()
151  {
152  if ($this->isSingleline && ($this->getThumbSize()))
153  {
154  foreach ($this->getAnswers() as $answer)
155  {
156  if (strlen($answer->getImage()))
157  {
158  $this->generateThumbForFile($this->getImagePath(), $answer->getImage());
159  }
160  }
161  }
162  }
163 
167  public function getThumbPrefix()
168  {
169  return "thumb.";
170  }
171 
176  protected function generateThumbForFile($path, $file)
177  {
178  $filename = $path . $file;
179  if (@file_exists($filename))
180  {
181  $thumbpath = $path . $this->getThumbPrefix() . $file;
182  $path_info = @pathinfo($filename);
183  $ext = "";
184  switch (strtoupper($path_info['extension']))
185  {
186  case 'PNG':
187  $ext = 'PNG';
188  break;
189  case 'GIF':
190  $ext = 'GIF';
191  break;
192  default:
193  $ext = 'JPEG';
194  break;
195  }
196  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbSize());
197  }
198  }
199 
205  public function loadFromDb($question_id)
206  {
207  global $ilDB;
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_mc WHERE question_fi = %s ORDER BY aorder ASC",
246  array('integer'),
247  array($question_id)
248  );
249  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.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_AnswerMultipleResponseImage($data["answertext"], $data["points"], $data["aorder"], $data["points_unchecked"], $data["imagefile"]));
262  }
263  }
264 
265  parent::loadFromDb($question_id);
266  }
267 
271  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
272  {
273  if ($this->id <= 0)
274  {
275  // The question has not been saved. It cannot be duplicated
276  return;
277  }
278  // duplicate the question in database
279  $this_id = $this->getId();
280  $thisObjId = $this->getObjId();
281 
282  $clone = $this;
283  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
285  $clone->id = -1;
286 
287  if( (int)$testObjId > 0 )
288  {
289  $clone->setObjId($testObjId);
290  }
291 
292  if ($title)
293  {
294  $clone->setTitle($title);
295  }
296 
297  if ($author)
298  {
299  $clone->setAuthor($author);
300  }
301  if ($owner)
302  {
303  $clone->setOwner($owner);
304  }
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  // copy XHTML media objects
318  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
319  // duplicate the images
320  $clone->duplicateImages($this_id, $thisObjId);
321 
322  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
323 
324  return $clone->id;
325  }
326 
330  public function copyObject($target_questionpool_id, $title = "")
331  {
332  if ($this->id <= 0)
333  {
334  // The question has not been saved. It cannot be duplicated
335  return;
336  }
337  // duplicate the question in database
338  $clone = $this;
339  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
341  $clone->id = -1;
342  $source_questionpool_id = $this->getObjId();
343  $clone->setObjId($target_questionpool_id);
344  if ($title)
345  {
346  $clone->setTitle($title);
347  }
348  $clone->saveToDb();
349  // copy question page content
350  $clone->copyPageOfQuestion($original_id);
351  // copy XHTML media objects
352  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
353  // duplicate the image
354  $clone->copyImages($original_id, $source_questionpool_id);
355 
356  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
357 
358  return $clone->id;
359  }
360 
361  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
362  {
363  if ($this->id <= 0)
364  {
365  // The question has not been saved. It cannot be duplicated
366  return;
367  }
368 
369  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
370 
371  $sourceQuestionId = $this->id;
372  $sourceParentId = $this->getObjId();
373 
374  // duplicate the question in database
375  $clone = $this;
376  $clone->id = -1;
377 
378  $clone->setObjId($targetParentId);
379 
380  if ($targetQuestionTitle)
381  {
382  $clone->setTitle($targetQuestionTitle);
383  }
384 
385  $clone->saveToDb();
386  // copy question page content
387  $clone->copyPageOfQuestion($sourceQuestionId);
388  // copy XHTML media objects
389  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
390  // duplicate the image
391  $clone->copyImages($sourceQuestionId, $sourceParentId);
392 
393  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
394 
395  return $clone->id;
396  }
397 
404  public function getOutputType()
405  {
406  return $this->output_type;
407  }
408 
417  {
418  $this->output_type = $output_type;
419  }
420 
434  public function addAnswer(
435  $answertext = "",
436  $points = 0.0,
437  $points_unchecked = 0.0,
438  $order = 0,
439  $answerimage = ""
440  )
441  {
442  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
443  if (array_key_exists($order, $this->answers))
444  {
445  // insert answer
446  $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, $order, $points_unchecked, $answerimage);
447  $newchoices = array();
448  for ($i = 0; $i < $order; $i++)
449  {
450  array_push($newchoices, $this->answers[$i]);
451  }
452  array_push($newchoices, $answer);
453  for ($i = $order; $i < count($this->answers); $i++)
454  {
455  $changed = $this->answers[$i];
456  $changed->setOrder($i+1);
457  array_push($newchoices, $changed);
458  }
459  $this->answers = $newchoices;
460  }
461  else
462  {
463  // add answer
464  $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, count($this->answers), $points_unchecked, $answerimage);
465  array_push($this->answers, $answer);
466  }
467  }
468 
475  public function getAnswerCount()
476  {
477  return count($this->answers);
478  }
479 
488  public function getAnswer($index = 0)
489  {
490  if ($index < 0) return NULL;
491  if (count($this->answers) < 1) return NULL;
492  if ($index >= count($this->answers)) return NULL;
493 
494  return $this->answers[$index];
495  }
496 
504  public function deleteAnswer($index = 0)
505  {
506  if ($index < 0) return;
507  if (count($this->answers) < 1) return;
508  if ($index >= count($this->answers)) return;
509  $answer = $this->answers[$index];
510  if (strlen($answer->getImage())) $this->deleteImage($answer->getImage());
511  unset($this->answers[$index]);
512  $this->answers = array_values($this->answers);
513  for ($i = 0; $i < count($this->answers); $i++)
514  {
515  if ($this->answers[$i]->getOrder() > $index)
516  {
517  $this->answers[$i]->setOrder($i);
518  }
519  }
520  }
521 
527  public function flushAnswers()
528  {
529  $this->answers = array();
530  }
531 
537  public function getMaximumPoints()
538  {
539  $points = 0;
540  $allpoints = 0;
541  foreach ($this->answers as $key => $value)
542  {
543  if ($value->getPoints() > $value->getPointsUnchecked())
544  {
545  $allpoints += $value->getPoints();
546  }
547  else
548  {
549  $allpoints += $value->getPointsUnchecked();
550  }
551  }
552  return $allpoints;
553  }
554 
566  public function calculateReachedPoints($active_id, $pass = NULL, $returndetails = FALSE)
567  {
568  if( $returndetails )
569  {
570  throw new ilTestException('return details not implemented for '.__METHOD__);
571  }
572 
573  global $ilDB;
574 
575  $found_values = array();
576  if (is_null($pass))
577  {
578  $pass = $this->getSolutionMaxPass($active_id);
579  }
580  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
581  array('integer','integer','integer'),
582  array($active_id, $this->getId(), $pass)
583  );
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 (in_array($key, $found_values))
595  {
596  $points += $answer->getPoints();
597  }
598  else
599  {
600  $points += $answer->getPointsUnchecked();
601  }
602  }
603  include_once "./Modules/Test/classes/class.ilObjTest.php";
604  $mc_scoring = ilObjTest::_getMCScoring($active_id);
605  if (($mc_scoring == 0) && (count($found_values) == 0))
606  {
607  $points = 0;
608  }
609  return $points;
610  }
611 
620  public function saveWorkingData($active_id, $pass = NULL)
621  {
623  global $ilDB;
624 
625  if (is_null($pass))
626  {
627  include_once "./Modules/Test/classes/class.ilObjTest.php";
628  $pass = ilObjTest::_getPass($active_id);
629  }
630 
631  $entered_values = 0;
632 
633  $this->getProcessLocker()->requestUserSolutionUpdateLock();
634 
635  $ilDB->manipulateF("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
636  array('integer','integer','integer'),
637  array($active_id, $this->getId(), $pass)
638  );
639  foreach ($_POST as $key => $value)
640  {
641  if (preg_match("/^multiple_choice_result_(\d+)/", $key, $matches))
642  {
643  if (strlen($value))
644  {
645  $next_id = $ilDB->nextId('tst_solutions');
646  $ilDB->insert("tst_solutions", array(
647  "solution_id" => array("integer", $next_id),
648  "active_fi" => array("integer", $active_id),
649  "question_fi" => array("integer", $this->getId()),
650  "value1" => array("clob", $value),
651  "value2" => array("clob", null),
652  "pass" => array("integer", $pass),
653  "tstamp" => array("integer", time())
654  ));
655  $entered_values++;
656  }
657  }
658  }
659 
660  $this->getProcessLocker()->releaseUserSolutionUpdateLock();
661 
662  if ($entered_values)
663  {
664  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
666  {
667  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
668  }
669  }
670  else
671  {
672  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
674  {
675  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
676  }
677  }
678 
679  return true;
680  }
681 
682  public function saveAdditionalQuestionDataToDb()
683  {
685  global $ilDB;
686  $oldthumbsize = 0;
687  if ($this->isSingleline && ($this->getThumbSize()))
688  {
689  // get old thumbnail size
690  $result = $ilDB->queryF( "SELECT thumb_size FROM " . $this->getAdditionalTableName(
691  ) . " WHERE question_fi = %s",
692  array( "integer" ),
693  array( $this->getId() )
694  );
695  if ($result->numRows() == 1)
696  {
697  $data = $ilDB->fetchAssoc( $result );
698  $oldthumbsize = $data['thumb_size'];
699  }
700  }
701 
702  if (!$this->isSingleline)
703  {
704  ilUtil::delDir( $this->getImagePath() );
705  }
706 
707  // save additional data
708  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
709  array( "integer" ),
710  array( $this->getId() )
711  );
712 
713  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName()
714  . " (question_fi, shuffle, allow_images, thumb_size) VALUES (%s, %s, %s, %s)",
715  array( "integer", "text", "text", "integer" ),
716  array(
717  $this->getId(),
718  $this->getShuffle(),
719  ($this->isSingleline) ? "0" : "1",
720  (strlen( $this->getThumbSize() ) == 0) ? null : $this->getThumbSize()
721  )
722  );
723  }
724 
725  public function saveAnswerSpecificDataToDb()
726  {
728  global $ilDB;
729  $ilDB->manipulateF( "DELETE FROM qpl_a_mc WHERE question_fi = %s",
730  array( 'integer' ),
731  array( $this->getId() )
732  );
733 
734  foreach ($this->answers as $key => $value)
735  {
736  $answer_obj = $this->answers[$key];
737  $next_id = $ilDB->nextId( 'qpl_a_mc' );
738  $ilDB->manipulateF( "INSERT INTO qpl_a_mc (answer_id, question_fi, answertext, points, points_unchecked, aorder, imagefile, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
739  array( 'integer', 'integer', 'text', 'float', 'float', 'integer', 'text', 'integer' ),
740  array(
741  $next_id,
742  $this->getId(),
743  ilRTE::_replaceMediaObjectImageSrc( $answer_obj->getAnswertext(), 0 ),
744  $answer_obj->getPoints(),
745  $answer_obj->getPointsUnchecked(),
746  $answer_obj->getOrder(),
747  $answer_obj->getImage(),
748  time()
749  )
750  );
751  }
752  $this->rebuildThumbnails();
753  }
754 
762  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
763  {
764  // nothing to rework!
765  }
766 
767  function syncWithOriginal()
768  {
769  if ($this->getOriginalId())
770  {
771  $this->syncImages();
773  }
774  }
775 
781  public function getQuestionType()
782  {
783  return "assMultipleChoice";
784  }
785 
791  public function getAdditionalTableName()
792  {
793  return "qpl_qst_mc";
794  }
795 
801  public function getAnswerTableName()
802  {
803  return "qpl_a_mc";
804  }
805 
813  public function setImageFile($image_filename, $image_tempfilename = "")
814  {
815  $result = 0;
816  if (!empty($image_tempfilename))
817  {
818  $image_filename = str_replace(" ", "_", $image_filename);
819  $imagepath = $this->getImagePath();
820  if (!file_exists($imagepath))
821  {
822  ilUtil::makeDirParents($imagepath);
823  }
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 
855  protected function deleteImage($image_filename)
856  {
857  $imagepath = $this->getImagePath();
858  @unlink($imagepath . $image_filename);
859  $thumbpath = $imagepath . $this->getThumbPrefix() . $image_filename;
860  @unlink($thumbpath);
861  }
862 
863  function duplicateImages($question_id, $objectId = null)
864  {
865  global $ilLog;
866  $imagepath = $this->getImagePath();
867  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
868 
869  if( (int)$objectId > 0 )
870  {
871  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
872  }
873 
874  foreach ($this->answers as $answer)
875  {
876  $filename = $answer->getImage();
877  if (strlen($filename))
878  {
879  if (!file_exists($imagepath))
880  {
881  ilUtil::makeDirParents($imagepath);
882  }
883  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
884  {
885  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
886  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
887  }
888  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
889  {
890  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
891  {
892  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
893  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
894  }
895  }
896  }
897  }
898  }
899 
900  function copyImages($question_id, $source_questionpool)
901  {
902  global $ilLog;
903  $imagepath = $this->getImagePath();
904  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
905  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
906  foreach ($this->answers as $answer)
907  {
908  $filename = $answer->getImage();
909  if (strlen($filename))
910  {
911  if (!file_exists($imagepath))
912  {
913  ilUtil::makeDirParents($imagepath);
914  }
915  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
916  {
917  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
918  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
919  }
920  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
921  {
922  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
923  {
924  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
925  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
926  }
927  }
928  }
929  }
930  }
931 
935  protected function syncImages()
936  {
937  global $ilLog;
938 
939  $imagepath = $this->getImagePath();
940 
941  $question_id = $this->getOriginalId();
942  $originalObjId = parent::lookupOriginalParentObjId($this->getOriginalId());
943  $imagepath_original = $this->getImagePath($question_id, $originalObjId);
944 
945  ilUtil::delDir($imagepath_original);
946  foreach ($this->answers as $answer)
947  {
948  $filename = $answer->getImage();
949  if (strlen($filename))
950  {
951  if (@file_exists($imagepath . $filename))
952  {
953  if (!file_exists($imagepath))
954  {
955  ilUtil::makeDirParents($imagepath);
956  }
957  if (!file_exists($imagepath_original))
958  {
959  ilUtil::makeDirParents($imagepath_original);
960  }
961  if (!@copy($imagepath . $filename, $imagepath_original . $filename))
962  {
963  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
964  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
965  }
966  }
967  if (@file_exists($imagepath . $this->getThumbPrefix() . $filename))
968  {
969  if (!@copy($imagepath . $this->getThumbPrefix() . $filename, $imagepath_original . $this->getThumbPrefix() . $filename))
970  {
971  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
972  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
973  }
974  }
975  }
976  }
977  }
978 
983  {
985  foreach ($this->answers as $index => $answer)
986  {
987  $text .= $this->feedbackOBJ->getSpecificAnswerFeedbackContent($this->getId(), $index);
988  $answer_obj = $this->answers[$index];
989  $text .= $answer_obj->getAnswertext();
990  }
991  return $text;
992  }
993 
997  function &getAnswers()
998  {
999  return $this->answers;
1000  }
1001 
1014  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
1015  {
1016  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1017  $solution = $this->getSolutionValues($active_id, $pass);
1018  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
1019  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
1020  $i = 1;
1021  foreach ($this->getAnswers() as $id => $answer)
1022  {
1023  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($answer->getAnswertext()), $format_bold);
1024  $checked = FALSE;
1025  foreach ($solution as $solutionvalue)
1026  {
1027  if ($id == $solutionvalue["value1"])
1028  {
1029  $checked = TRUE;
1030  }
1031  }
1032  if ($checked)
1033  {
1034  $worksheet->write($startrow + $i, 1, 1);
1035  }
1036  else
1037  {
1038  $worksheet->write($startrow + $i, 1, 0);
1039  }
1040  $i++;
1041  }
1042  return $startrow + $i + 1;
1043  }
1044 
1045  public function getThumbSize()
1046  {
1047  return $this->thumb_size;
1048  }
1049 
1050  public function setThumbSize($a_size)
1051  {
1052  $this->thumb_size = $a_size;
1053  }
1054 
1058  public function toJSON()
1059  {
1060  require_once './Services/RTE/classes/class.ilRTE.php';
1061  $result = array();
1062  $result['id'] = (int) $this->getId();
1063  $result['type'] = (string) $this->getQuestionType();
1064  $result['title'] = (string) $this->getTitle();
1065  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1066  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1067  $result['shuffle'] = (bool) $this->getShuffle();
1068  $result['feedback'] = array(
1069  "onenotcorrect" => $this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false),
1070  "allcorrect" => $this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true)
1071  );
1072 
1073  $answers = array();
1074  $has_image = false;
1075  foreach ($this->getAnswers() as $key => $answer_obj)
1076  {
1077  if((string) $answer_obj->getImage())
1078  {
1079  $has_image = true;
1080  }
1081  array_push($answers, array(
1082  "answertext" => (string) $this->formatSAQuestion($answer_obj->getAnswertext()),
1083  "points_checked" => (float) $answer_obj->getPointsChecked(),
1084  "points_unchecked" => (float) $answer_obj->getPointsUnchecked(),
1085  "order" => (int) $answer_obj->getOrder(),
1086  "image" => (string) $answer_obj->getImage(),
1087  "feedback" => ilRTE::_replaceMediaObjectImageSrc(
1088  $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), $key), 0
1089  )
1090  ));
1091  }
1092  $result['answers'] = $answers;
1093 
1094  if($has_image)
1095  {
1096  $result['path'] = $this->getImagePathWeb();
1097  $result['thumb'] = $this->getThumbSize();
1098  }
1099 
1100  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1101  $result['mobs'] = $mobs;
1102 
1103  return json_encode($result);
1104  }
1105 
1106  public function removeAnswerImage($index)
1107  {
1108  $answer = $this->answers[$index];
1109  if (is_object($answer))
1110  {
1111  $this->deleteImage($answer->getImage());
1112  $answer->setImage('');
1113  }
1114  }
1115 
1117  {
1118  global $ilUser;
1119 
1120  $multilineAnswerSetting = $ilUser->getPref("tst_multiline_answers");
1121  if ($multilineAnswerSetting != 1)
1122  {
1123  $multilineAnswerSetting = 0;
1124  }
1125  return $multilineAnswerSetting;
1126  }
1127 
1128  function setMultilineAnswerSetting($a_setting = 0)
1129  {
1130  global $ilUser;
1131  $ilUser->writePref("tst_multiline_answers", $a_setting);
1132  }
1133 
1143  function setSpecificFeedbackSetting($a_feedback_setting)
1144  {
1145  $this->feedback_setting = $a_feedback_setting;
1146  }
1147 
1158  {
1159  if ($this->feedback_setting)
1160  {
1161  return $this->feedback_setting;
1162  }
1163  else
1164  {
1165  return 1;
1166  }
1167  }
1168 
1180  public function isAnswered($active_id, $pass)
1181  {
1182  $answered = assQuestion::doesSolutionRecordsExist($active_id, $pass, $this->getId());
1183 
1184  return $answered;
1185  }
1186 
1198  public static function isObligationPossible($questionId)
1199  {
1201  global $ilDB;
1202 
1203  $query = "
1204  SELECT SUM(points) points_for_checked_answers
1205  FROM qpl_a_mc
1206  WHERE question_fi = %s
1207  ";
1208 
1209  $res = $ilDB->queryF($query, array('integer'), array($questionId));
1210 
1211  $row = $ilDB->fetchAssoc($res);
1212 
1213  return $row['points_for_checked_answers'] > 0;
1214  }
1215 
1224  public function ensureNoInvalidObligation($questionId)
1225  {
1227  global $ilDB;
1228 
1229  $query = "
1230  SELECT SUM(qpl_a_mc.points) points_for_checked_answers,
1231  test_question_id
1232 
1233  FROM tst_test_question
1234 
1235  INNER JOIN qpl_a_mc
1236  ON qpl_a_mc.question_fi = tst_test_question.question_fi
1237 
1238  WHERE tst_test_question.question_fi = %s
1239  AND tst_test_question.obligatory = 1
1240 
1241  GROUP BY test_question_id
1242  ";
1243 
1244  $res = $ilDB->queryF($query, array('integer'), array($questionId));
1245 
1246  $updateTestQuestionIds = array();
1247 
1248  while( $row = $ilDB->fetchAssoc($res) )
1249  {
1250  if( $row['points_for_checked_answers'] <= 0 )
1251  {
1252  $updateTestQuestionIds[] = $row['test_question_id'];
1253  }
1254  }
1255 
1256  if( count($updateTestQuestionIds) )
1257  {
1258  $test_question_id__IN__updateTestQuestionIds = $ilDB->in(
1259  'test_question_id', $updateTestQuestionIds, false, 'integer'
1260  );
1261 
1262  $query = "
1263  UPDATE tst_test_question
1264  SET obligatory = 0
1265  WHERE $test_question_id__IN__updateTestQuestionIds
1266  ";
1267 
1268  $ilDB->manipulate($query);
1269  }
1270  }
1271 }