ILIAS  release_4-4 Revision
All Data Structures Namespaces Files Functions Variables Modules 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 = "",
104  $output_type = OUTPUT_ORDER
105  )
106  {
107  parent::__construct($title, $comment, $author, $owner, $question);
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());
144  parent::saveToDb($original_id);
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 
416  public function setOutputType($output_type = OUTPUT_ORDER)
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();
772  parent::syncWithOriginal();
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  {
984  $text = parent::getRTETextWithMediaObjects();
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 }
flushAnswers()
Deletes all answers.
static isObligationPossible($questionId)
returns boolean wether it is possible to set this question type as obligatory or not considering the ...
static makeDirParents($a_dir)
Create a new directory and all parent directories.
getId()
Gets the id of the assQuestion object.
addAnswer( $answertext="", $points=0.0, $points_unchecked=0.0, $order=0, $answerimage="")
Adds a possible answer for a multiple choice question.
print $file
duplicateImages($question_id, $objectId=null)
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
toJSON()
Returns a JSON representation of the question.
generateThumbForFile($path, $file)
$_POST['username']
Definition: cron.php:12
static doesSolutionRecordsExist($activeId, $pass, $questionId)
checks wether there are existing solution records for the given test active / pass and given question...
isComplete()
Returns true, if a multiple choice question is complete for use.
isAnswered($active_id, $pass)
returns boolean wether the question is answered during test pass or not
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assMultipleChoiceQuestion.
copyObject($target_questionpool_id, $title="")
Copies an assMultipleChoice object.
$result
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
rebuildThumbnails()
Rebuild the thumbnail images with a new thumbnail size.
& getSolutionValues($active_id, $pass=NULL)
Loads solutions of a given user from the database an returns it.
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.
_convert_text($a_text, $a_target="has been removed")
ASS_AnswerBinaryStateImage is a class for answers with a binary state indicator (checked/unchecked, set/unset) and an image file.
setId($id=-1)
Sets the id of the assQuestion object.
_getMCScoring($active_id)
Gets the scoring type for multiple choice questions.
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.
setOutputType($output_type=OUTPUT_ORDER)
Sets the output type of the assMultipleChoice object.
getQuestionType()
Returns the question type of the question.
setNrOfTries($a_nr_of_tries)
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
loadFromDb($question_id)
Loads a assMultipleChoice object from a database.
setShuffle($shuffle=true)
Sets the shuffle flag.
Class for multiple choice tests.
getObjId()
Get the object id of the container object.
getShuffle()
Gets the shuffle flag.
Base Exception for all Exceptions relating to Modules/Test.
static getMimeType($a_file)
get mime type for file
$mobs
saveToDb($original_id="")
Saves a assMultipleChoice object to a database.
deleteAnswer($index=0)
Deletes an answer with a given index.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
fetchAssoc($a_set)
Fetch row as associative array from result set.
setAuthor($author="")
Sets the authors name of the assQuestion object.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
getAnswerCount()
Returns the number of answers.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
getSpecificFeedbackSetting()
Gets the current feedback settings in effect for the question.
Interface ilObjAnswerScoringAdjustable.
getQuestion()
Gets the question string of the question object.
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $output_type=OUTPUT_ORDER)
assMultipleChoice constructor
syncImages()
Sync images of a MC question on synchronisation with the original question.
setIsSingleline($isSingleline)
getAnswer($index=0)
Returns an answer with a given index.
& getAnswers()
Returns a reference to the answers array.
setSpecificFeedbackSetting($a_feedback_setting)
Sets the feedback settings in effect for the question.
deleteImage($image_filename)
Deletes an image file.
_getLogLanguage()
retrieve the log language for assessment logging
$filename
Definition: buildRTE.php:89
_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="")
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0)
replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
setImageFile($image_filename, $image_tempfilename="")
Sets the image file and uploads the image to the object&#39;s image directory.
calculateReachedPoints($active_id, $pass=NULL, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
while($lm_rec=$ilDB->fetchAssoc($lm_set)) $data
global $ilUser
Definition: imgupload.php:15
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
Interface ilObjQuestionScoringAdjustable.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
$path
Definition: index.php:22
setOriginalId($original_id)
getAnswerTableName()
Returns the name of the answer table in the database.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getTitle()
Gets the title string of the assQuestion object.
const OUTPUT_ORDER
getOutputType()
Gets the multiple choice output type which is either OUTPUT_ORDER (=0) or OUTPUT_RANDOM (=1)...
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.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
setMultilineAnswerSetting($a_setting=0)
copyImages($question_id, $source_questionpool)
saveWorkingData($active_id, $pass=NULL)
Saves the learners input of the question to the database.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.