ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assMultipleChoice.php
Go to the documentation of this file.
1 <?php
2  /*
3  +----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +----------------------------------------------------------------------------+
22 */
23 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
24 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
25 
36 {
44  var $answers;
45 
55 
61  protected $thumb_size;
62 
77  function __construct(
78  $title = "",
79  $comment = "",
80  $author = "",
81  $owner = -1,
82  $question = "",
84  )
85  {
87  $this->output_type = $output_type;
88  $this->thumb_size = 150;
89  $this->answers = array();
90  $this->shuffle = 1;
91  }
92 
99  function isComplete()
100  {
101  if (strlen($this->title) and ($this->author) and ($this->question) and (count($this->answers)) and ($this->getMaximumPoints() > 0))
102  {
103  return true;
104  }
105  else
106  {
107  return false;
108  }
109  }
110 
117  function saveToDb($original_id = "")
118  {
119  global $ilDB;
120 
122 
123  $oldthumbsize = 0;
124  if ($this->isSingleline && ($this->getThumbSize()))
125  {
126  // get old thumbnail size
127  $result = $ilDB->queryF("SELECT thumb_size FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
128  array("integer"),
129  array($this->getId())
130  );
131  if ($result->numRows() == 1)
132  {
133  $data = $ilDB->fetchAssoc($result);
134  $oldthumbsize = $data['thumb_size'];
135  }
136  }
137  if (!$this->isSingleline)
138  {
139  ilUtil::delDir($this->getImagePath());
140  }
141 
142  // save additional data
143  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
144  array("integer"),
145  array($this->getId())
146  );
147 
148  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, shuffle, allow_images, thumb_size) VALUES (%s, %s, %s, %s)",
149  array("integer", "text", "text", "integer"),
150  array(
151  $this->getId(),
152  $this->getShuffle(),
153  ($this->isSingleline) ? "0" : "1",
154  (strlen($this->getThumbSize()) == 0) ? null : $this->getThumbSize()
155  )
156  );
157 
158  $affectedRows = $ilDB->manipulateF("DELETE FROM qpl_a_mc WHERE question_fi = %s",
159  array('integer'),
160  array($this->getId())
161  );
162 
163  foreach ($this->answers as $key => $value)
164  {
165  $answer_obj = $this->answers[$key];
166  $next_id = $ilDB->nextId('qpl_a_mc');
167  $affectedRows = $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)",
168  array('integer','integer','text','float','float','integer','text', 'integer'),
169  array(
170  $next_id,
171  $this->getId(),
172  ilRTE::_replaceMediaObjectImageSrc($answer_obj->getAnswertext(), 0),
173  $answer_obj->getPoints(),
174  $answer_obj->getPointsUnchecked(),
175  $answer_obj->getOrder(),
176  $answer_obj->getImage(),
177  time()
178  )
179  );
180  }
181 
182  $this->rebuildThumbnails();
183 
185  }
186 
187  /*
188  * Rebuild the thumbnail images with a new thumbnail size
189  */
190  protected function rebuildThumbnails()
191  {
192  if ($this->isSingleline && ($this->getThumbSize()))
193  {
194  foreach ($this->getAnswers() as $answer)
195  {
196  if (strlen($answer->getImage()))
197  {
198  $this->generateThumbForFile($this->getImagePath(), $answer->getImage());
199  }
200  }
201  }
202  }
203 
204  public function getThumbPrefix()
205  {
206  return "thumb.";
207  }
208 
209  protected function generateThumbForFile($path, $file)
210  {
211  $filename = $path . $file;
212  if (@file_exists($filename))
213  {
214  $thumbpath = $path . $this->getThumbPrefix() . $file;
215  $path_info = @pathinfo($filename);
216  $ext = "";
217  switch (strtoupper($path_info['extension']))
218  {
219  case 'PNG':
220  $ext = 'PNG';
221  break;
222  case 'GIF':
223  $ext = 'GIF';
224  break;
225  default:
226  $ext = 'JPEG';
227  break;
228  }
229  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbSize());
230  }
231  }
232 
239  function loadFromDb($question_id)
240  {
241  global $ilDB;
242  $hasimages = 0;
243 
244  $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",
245  array("integer"),
246  array($question_id)
247  );
248  if ($result->numRows() == 1)
249  {
250  $data = $ilDB->fetchAssoc($result);
251  $this->setId($question_id);
252  $this->setObjId($data["obj_fi"]);
253  $this->setTitle($data["title"]);
254  $this->setNrOfTries($data['nr_of_tries']);
255  $this->setComment($data["description"]);
256  $this->setOriginalId($data["original_id"]);
257  $this->setAuthor($data["author"]);
258  $this->setPoints($data["points"]);
259  $this->setOwner($data["owner"]);
260  include_once("./Services/RTE/classes/class.ilRTE.php");
261  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
262  $shuffle = (is_null($data['shuffle'])) ? true : $data['shuffle'];
263  $this->setShuffle($shuffle);
264  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
265  $this->setThumbSize($data['thumb_size']);
266  $this->isSingleline = ($data['allow_images']) ? false : true;
267  $this->lastChange = $data['tstamp'];
268  }
269 
270  $result = $ilDB->queryF("SELECT * FROM qpl_a_mc WHERE question_fi = %s ORDER BY aorder ASC",
271  array('integer'),
272  array($question_id)
273  );
274  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
275  if ($result->numRows() > 0)
276  {
277  while ($data = $ilDB->fetchAssoc($result))
278  {
279  $imagefilename = $this->getImagePath() . $data["imagefile"];
280  if (!@file_exists($imagefilename))
281  {
282  $data["imagefile"] = "";
283  }
284  include_once("./Services/RTE/classes/class.ilRTE.php");
285  $data["answertext"] = ilRTE::_replaceMediaObjectImageSrc($data["answertext"], 1);
286  array_push($this->answers, new ASS_AnswerMultipleResponseImage($data["answertext"], $data["points"], $data["aorder"], $data["points_unchecked"], $data["imagefile"]));
287  }
288  }
289 
290  parent::loadFromDb($question_id);
291  }
292 
298  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
299  {
300  if ($this->id <= 0)
301  {
302  // The question has not been saved. It cannot be duplicated
303  return;
304  }
305  // duplicate the question in database
306  $this_id = $this->getId();
307 
308  if( (int)$testObjId > 0 )
309  {
310  $thisObjId = $this->getObjId();
311  }
312 
313  $clone = $this;
314  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
316  $clone->id = -1;
317 
318  if( (int)$testObjId > 0 )
319  {
320  $clone->setObjId($testObjId);
321  }
322 
323  if ($title)
324  {
325  $clone->setTitle($title);
326  }
327 
328  if ($author)
329  {
330  $clone->setAuthor($author);
331  }
332  if ($owner)
333  {
334  $clone->setOwner($owner);
335  }
336 
337  if ($for_test)
338  {
339  $clone->saveToDb($original_id);
340  }
341  else
342  {
343  $clone->saveToDb();
344  }
345 
346  // copy question page content
347  $clone->copyPageOfQuestion($this_id);
348  // copy XHTML media objects
349  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
350  // duplicate the images
351  $clone->duplicateImages($this_id, $thisObjId);
352  // duplicate the generic feedback
353  $clone->duplicateFeedbackGeneric($this_id);
354  // duplicate the answer specific feedback
355  $clone->duplicateFeedbackAnswer($this_id);
356 
357  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
358 
359  return $clone->id;
360  }
361 
367  function copyObject($target_questionpool, $title = "")
368  {
369  if ($this->id <= 0)
370  {
371  // The question has not been saved. It cannot be duplicated
372  return;
373  }
374  // duplicate the question in database
375  $clone = $this;
376  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
378  $clone->id = -1;
379  $source_questionpool = $this->getObjId();
380  $clone->setObjId($target_questionpool);
381  if ($title)
382  {
383  $clone->setTitle($title);
384  }
385  $clone->saveToDb();
386 
387  // copy question page content
388  $clone->copyPageOfQuestion($original_id);
389  // copy XHTML media objects
390  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
391  // duplicate the image
392  $clone->copyImages($original_id, $source_questionpool);
393  // duplicate the generic feedback
394  $clone->duplicateFeedbackGeneric($original_id);
395  // duplicate the answer specific feedback
396  $clone->duplicateFeedbackAnswer($original_id);
397 
398  $clone->onDuplicate($source_questionpool, $this->getId());
399 
400  $clone->onCopy($this->getObjId(), $this->getId());
401  return $clone->id;
402  }
403 
411  function getOutputType()
412  {
413  return $this->output_type;
414  }
415 
424  {
425  $this->output_type = $output_type;
426  }
427 
441  function addAnswer(
442  $answertext = "",
443  $points = 0.0,
444  $points_unchecked = 0.0,
445  $order = 0,
446  $answerimage = ""
447  )
448  {
449  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMultipleResponseImage.php";
450  if (array_key_exists($order, $this->answers))
451  {
452  // insert answer
453  $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, $order, $points_unchecked, $answerimage);
454  $newchoices = array();
455  for ($i = 0; $i < $order; $i++)
456  {
457  array_push($newchoices, $this->answers[$i]);
458  }
459  array_push($newchoices, $answer);
460  for ($i = $order; $i < count($this->answers); $i++)
461  {
462  $changed = $this->answers[$i];
463  $changed->setOrder($i+1);
464  array_push($newchoices, $changed);
465  }
466  $this->answers = $newchoices;
467  }
468  else
469  {
470  // add answer
471  $answer = new ASS_AnswerMultipleResponseImage($answertext, $points, count($this->answers), $points_unchecked, $answerimage);
472  array_push($this->answers, $answer);
473  }
474  }
475 
483  function getAnswerCount()
484  {
485  return count($this->answers);
486  }
487 
497  function getAnswer($index = 0)
498  {
499  if ($index < 0) return NULL;
500  if (count($this->answers) < 1) return NULL;
501  if ($index >= count($this->answers)) return NULL;
502 
503  return $this->answers[$index];
504  }
505 
514  function deleteAnswer($index = 0)
515  {
516  if ($index < 0) return;
517  if (count($this->answers) < 1) return;
518  if ($index >= count($this->answers)) return;
519  $answer = $this->answers[$index];
520  if (strlen($answer->getImage())) $this->deleteImage($answer->getImage());
521  unset($this->answers[$index]);
522  $this->answers = array_values($this->answers);
523  for ($i = 0; $i < count($this->answers); $i++)
524  {
525  if ($this->answers[$i]->getOrder() > $index)
526  {
527  $this->answers[$i]->setOrder($i);
528  }
529  }
530  }
531 
538  function flushAnswers()
539  {
540  $this->answers = array();
541  }
542 
549  function getMaximumPoints()
550  {
551  $points = 0;
552  $allpoints = 0;
553  foreach ($this->answers as $key => $value)
554  {
555  if ($value->getPoints() > $value->getPointsUnchecked())
556  {
557  $allpoints += $value->getPoints();
558  }
559  else
560  {
561  $allpoints += $value->getPointsUnchecked();
562  }
563  }
564  return $allpoints;
565  }
566 
576  function calculateReachedPoints($active_id, $pass = NULL)
577  {
578  global $ilDB;
579 
580  $found_values = array();
581  if (is_null($pass))
582  {
583  $pass = $this->getSolutionMaxPass($active_id);
584  }
585  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
586  array('integer','integer','integer'),
587  array($active_id, $this->getId(), $pass)
588  );
589  while ($data = $ilDB->fetchAssoc($result))
590  {
591  if (strcmp($data["value1"], "") != 0)
592  {
593  array_push($found_values, $data["value1"]);
594  }
595  }
596  $points = 0;
597  foreach ($this->answers as $key => $answer)
598  {
599  if (in_array($key, $found_values))
600  {
601  $points += $answer->getPoints();
602  }
603  else
604  {
605  $points += $answer->getPointsUnchecked();
606  }
607  }
608  include_once "./Modules/Test/classes/class.ilObjTest.php";
609  $mc_scoring = ilObjTest::_getMCScoring($active_id);
610  if (($mc_scoring == 0) && (count($found_values) == 0))
611  {
612  $points = 0;
613  }
614  $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
615  return $points;
616  }
617 
626  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 
637  $entered_values = 0;
638  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s",
639  array('integer','integer','integer'),
640  array($active_id, $this->getId(), $pass)
641  );
642  foreach ($_POST as $key => $value)
643  {
644  if (preg_match("/^multiple_choice_result_(\d+)/", $key, $matches))
645  {
646  if (strlen($value))
647  {
648  $next_id = $ilDB->nextId('tst_solutions');
649  $affectedRows = $ilDB->insert("tst_solutions", array(
650  "solution_id" => array("integer", $next_id),
651  "active_fi" => array("integer", $active_id),
652  "question_fi" => array("integer", $this->getId()),
653  "value1" => array("clob", $value),
654  "value2" => array("clob", null),
655  "pass" => array("integer", $pass),
656  "tstamp" => array("integer", time())
657  ));
658  $entered_values++;
659  }
660  }
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  parent::saveWorkingData($active_id, $pass);
679  return true;
680  }
681 
687  function syncFeedbackSingleAnswers()
688  {
689  global $ilDB;
690 
691  $feedback = "";
692 
693  // delete generic feedback of the original
694  $affectedRows = $ilDB->manipulateF("DELETE FROM qpl_fb_mc WHERE question_fi = %s",
695  array('integer'),
696  array($this->original_id)
697  );
698 
699  // get generic feedback of the actual question
700  $result = $ilDB->queryF("SELECT * FROM qpl_fb_mc WHERE question_fi = %s",
701  array('integer'),
702  array($this->getId())
703  );
704  // save generic feedback to the original
705  if ($result->numRows())
706  {
707  while ($row = $ilDB->fetchAssoc($result))
708  {
709  $next_id = $ilDB->nextId('qpl_fb_mc');
710 
712  $ilDB->insert('qpl_fb_mc', array(
713  'feedback_id' => array( 'integer', $next_id ),
714  'question_fi' => array( 'integer', $this->original_id ),
715  'answer' => array( 'integer', $row["answer"] ),
716  'feedback' => array( 'clob', $row["feedback"] ),
717  'tstamp' => array( 'integer', time() ),
718  )
719  );
720  }
721  }
722  }
723 
724  function syncWithOriginal()
725  {
726  if ($this->getOriginalId())
727  {
728  $this->syncFeedbackSingleAnswers();
729  $this->syncImages();
731  }
732  }
733 
740  function getQuestionType()
741  {
742  return "assMultipleChoice";
743  }
744 
752  {
753  return "qpl_qst_mc";
754  }
755 
763  {
764  return "qpl_a_mc";
765  }
766 
775  function setImageFile($image_filename, $image_tempfilename = "")
776  {
777  $result = 0;
778  if (!empty($image_tempfilename))
779  {
780  $image_filename = str_replace(" ", "_", $image_filename);
781  $imagepath = $this->getImagePath();
782  if (!file_exists($imagepath))
783  {
784  ilUtil::makeDirParents($imagepath);
785  }
786  //if (!move_uploaded_file($image_tempfilename, $imagepath . $image_filename))
787  if (!ilUtil::moveUploadedFile($image_tempfilename, $image_filename, $imagepath.$image_filename))
788  {
789  $result = 2;
790  }
791  else
792  {
793  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
794  $mimetype = ilObjMediaObject::getMimeType($imagepath . $image_filename);
795  if (!preg_match("/^image/", $mimetype))
796  {
797  unlink($imagepath . $image_filename);
798  $result = 1;
799  }
800  else
801  {
802  // create thumbnail file
803  if ($this->isSingleline && ($this->getThumbSize()))
804  {
805  $this->generateThumbForFile($imagepath, $image_filename);
806  }
807  }
808  }
809  }
810  return $result;
811  }
812 
819  function deleteImage($image_filename)
820  {
821  $imagepath = $this->getImagePath();
822  @unlink($imagepath . $image_filename);
823  $thumbpath = $imagepath . $this->getThumbPrefix() . $image_filename;
824  @unlink($thumbpath);
825  }
826 
827  function duplicateImages($question_id, $objectId = null)
828  {
829  global $ilLog;
830  $imagepath = $this->getImagePath();
831  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
832 
833  if( (int)$objectId > 0 )
834  {
835  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
836  }
837 
838  foreach ($this->answers as $answer)
839  {
840  $filename = $answer->getImage();
841  if (strlen($filename))
842  {
843  if (!file_exists($imagepath))
844  {
845  ilUtil::makeDirParents($imagepath);
846  }
847  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
848  {
849  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
850  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
851  }
852  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
853  {
854  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
855  {
856  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
857  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
858  }
859  }
860  }
861  }
862  }
863 
864  function copyImages($question_id, $source_questionpool)
865  {
866  global $ilLog;
867  $imagepath = $this->getImagePath();
868  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
869  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
870  foreach ($this->answers as $answer)
871  {
872  $filename = $answer->getImage();
873  if (strlen($filename))
874  {
875  if (!file_exists($imagepath))
876  {
877  ilUtil::makeDirParents($imagepath);
878  }
879  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
880  {
881  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
882  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
883  }
884  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
885  {
886  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
887  {
888  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
889  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
890  }
891  }
892  }
893  }
894  }
895 
899  protected function syncImages()
900  {
901  global $ilLog;
902  $question_id = $this->getOriginalId();
903  $imagepath = $this->getImagePath();
904  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
905  ilUtil::delDir($imagepath_original);
906  foreach ($this->answers as $answer)
907  {
908  $filename = $answer->getImage();
909  if (strlen($filename))
910  {
911  if (@file_exists($imagepath . $filename))
912  {
913  if (!file_exists($imagepath))
914  {
915  ilUtil::makeDirParents($imagepath);
916  }
917  if (!file_exists($imagepath_original))
918  {
919  ilUtil::makeDirParents($imagepath_original);
920  }
921  if (!@copy($imagepath . $filename, $imagepath_original . $filename))
922  {
923  $ilLog->write("image could not be duplicated!!!!", $ilLog->ERROR);
924  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
925  }
926  }
927  if (@file_exists($imagepath . $this->getThumbPrefix() . $filename))
928  {
929  if (!@copy($imagepath . $this->getThumbPrefix() . $filename, $imagepath_original . $this->getThumbPrefix() . $filename))
930  {
931  $ilLog->write("image thumbnail could not be duplicated!!!!", $ilLog->ERROR);
932  $ilLog->write("object: " . print_r($this, TRUE), $ilLog->ERROR);
933  }
934  }
935  }
936  }
937  }
938 
946  function saveFeedbackSingleAnswer($answer_index, $feedback)
947  {
948  global $ilDB;
949 
950  $affectedRows = $ilDB->manipulateF("DELETE FROM qpl_fb_mc WHERE question_fi = %s AND answer = %s",
951  array('integer','integer'),
952  array($this->getId(), $answer_index)
953  );
954  if (strlen($feedback))
955  {
956  include_once("./Services/RTE/classes/class.ilRTE.php");
957  $next_id = $ilDB->nextId('qpl_fb_mc');
958 
960  $ilDB->insert('qpl_fb_mc', array(
961  'feedback_id' => array( 'integer', $next_id ),
962  'question_fi' => array( 'integer', $this->getId() ),
963  'answer' => array( 'integer', $answer_index ),
964  'feedback' => array( 'clob', ilRTE::_replaceMediaObjectImageSrc( $feedback, 0 ) ),
965  'tstamp' => array( 'integer', time() ),
966  )
967  );
968  }
969  }
970 
978  function getFeedbackSingleAnswer($answer_index)
979  {
980  global $ilDB;
981 
982  $feedback = "";
983  $result = $ilDB->queryF("SELECT * FROM qpl_fb_mc WHERE question_fi = %s AND answer = %s",
984  array('integer','integer'),
985  array($this->getId(), $answer_index)
986  );
987  if ($result->numRows())
988  {
989  $row = $ilDB->fetchAssoc($result);
990  include_once("./Services/RTE/classes/class.ilRTE.php");
991  $feedback = ilRTE::_replaceMediaObjectImageSrc($row["feedback"], 1);
992  }
993  return $feedback;
994  }
995 
1002  function duplicateFeedbackAnswer($original_id)
1003  {
1004  global $ilDB;
1005 
1006  $feedback = "";
1007  $result = $ilDB->queryF("SELECT * FROM qpl_fb_mc WHERE question_fi = %s",
1008  array('integer'),
1009  array($original_id)
1010  );
1011  if ($result->numRows())
1012  {
1013  while ($row = $ilDB->fetchAssoc($result))
1014  {
1015  $next_id = $ilDB->nextId('qpl_fb_mc');
1016 
1018  $ilDB->insert('qpl_fb_mc', array(
1019  'feedback_id' => array( 'integer', $next_id ),
1020  'question_fi' => array( 'integer', $this->getId() ),
1021  'answer' => array( 'integer', $row["answer"] ),
1022  'feedback' => array( 'clob', $row["feedback"] ),
1023  'tstamp' => array( 'integer', time() ),
1024  )
1025  );
1026 
1027  }
1028  }
1029  }
1030 
1036  {
1038  foreach ($this->answers as $index => $answer)
1039  {
1040  $text .= $this->getFeedbackSingleAnswer($index);
1041  $answer_obj = $this->answers[$index];
1042  $text .= $answer_obj->getAnswertext();
1043  }
1044  return $text;
1045  }
1046 
1050  function &getAnswers()
1051  {
1052  return $this->answers;
1053  }
1054 
1067  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
1068  {
1069  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1070  $solution = $this->getSolutionValues($active_id, $pass);
1071  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
1072  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
1073  $i = 1;
1074  foreach ($this->getAnswers() as $id => $answer)
1075  {
1076  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($answer->getAnswertext()), $format_bold);
1077  $checked = FALSE;
1078  foreach ($solution as $solutionvalue)
1079  {
1080  if ($id == $solutionvalue["value1"])
1081  {
1082  $checked = TRUE;
1083  }
1084  }
1085  if ($checked)
1086  {
1087  $worksheet->write($startrow + $i, 1, 1);
1088  }
1089  else
1090  {
1091  $worksheet->write($startrow + $i, 1, 0);
1092  }
1093  $i++;
1094  }
1095  return $startrow + $i + 1;
1096  }
1097 
1098  public function getThumbSize()
1099  {
1100  return $this->thumb_size;
1101  }
1102 
1103  public function setThumbSize($a_size)
1104  {
1105  $this->thumb_size = $a_size;
1106  }
1107 
1111  public function toJSON()
1112  {
1113  include_once("./Services/RTE/classes/class.ilRTE.php");
1114  $result = array();
1115  $result['id'] = (int) $this->getId();
1116  $result['type'] = (string) $this->getQuestionType();
1117  $result['title'] = (string) $this->getTitle();
1118  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1119  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1120  $result['shuffle'] = (bool) $this->getShuffle();
1121  $result['feedback'] = array(
1122  "onenotcorrect" => nl2br(ilRTE::_replaceMediaObjectImageSrc($this->getFeedbackGeneric(0), 0)),
1123  "allcorrect" => nl2br(ilRTE::_replaceMediaObjectImageSrc($this->getFeedbackGeneric(1), 0))
1124  );
1125 
1126  $answers = array();
1127  $has_image = false;
1128  foreach ($this->getAnswers() as $key => $answer_obj)
1129  {
1130  if((string) $answer_obj->getImage())
1131  {
1132  $has_image = true;
1133  }
1134  array_push($answers, array(
1135  "answertext" => (string) $answer_obj->getAnswertext(),
1136  "points_checked" => (float) $answer_obj->getPointsChecked(),
1137  "points_unchecked" => (float) $answer_obj->getPointsUnchecked(),
1138  "order" => (int) $answer_obj->getOrder(),
1139  "image" => (string) $answer_obj->getImage(),
1140  "feedback" => ilRTE::_replaceMediaObjectImageSrc($this->getFeedbackSingleAnswer($key), 0)
1141  ));
1142  }
1143  $result['answers'] = $answers;
1144 
1145  if($has_image)
1146  {
1147  $result['path'] = $this->getImagePathWeb();
1148  $result['thumb'] = $this->getThumbSize();
1149  }
1150 
1151  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1152  $result['mobs'] = $mobs;
1153 
1154  return json_encode($result);
1155  }
1156 
1157  public function removeAnswerImage($index)
1158  {
1159  $answer = $this->answers[$index];
1160  if (is_object($answer))
1161  {
1162  $this->deleteImage($answer->getImage());
1163  $answer->setImage('');
1164  }
1165  }
1166 
1168  {
1169  global $ilUser;
1170 
1171  $multilineAnswerSetting = $ilUser->getPref("tst_multiline_answers");
1172  if ($multilineAnswerSetting != 1)
1173  {
1174  $multilineAnswerSetting = 0;
1175  }
1176  return $multilineAnswerSetting;
1177  }
1178 
1179  function setMultilineAnswerSetting($a_setting = 0)
1180  {
1181  global $ilUser;
1182  $ilUser->writePref("tst_multiline_answers", $a_setting);
1183  }
1184 }
1185 
1186 ?>