ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
class.assOrderingQuestion.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 
11 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssOrderingElementList.php';
12 
27 {
28  const ORDERING_ELEMENT_FORM_FIELD_POSTVAR = 'order_elems';
29 
30  const ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG = 'uploadElementImage';
31  const ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG = 'removeElementImage';
32 
37 
47 
53  public $thumb_geometry = 100;
54 
61 
62  public $old_ordering_depth = array();
63  public $leveled_ordering = array();
64 
77  public function __construct(
78  $title = "",
79  $comment = "",
80  $author = "",
81  $owner = -1,
82  $question = "",
84  ) {
86  $this->orderingElementList = new ilAssOrderingElementList();
87  $this->ordering_type = $ordering_type;
88  }
89 
95  public function isComplete()
96  {
97  if (!$this->getAuthor()) {
98  return false;
99  }
100 
101  if (!$this->getTitle()) {
102  return false;
103  }
104 
105  if (!$this->getQuestion()) {
106  return false;
107  }
108 
109  if (!$this->getMaximumPoints()) {
110  return false;
111  }
112 
113  if (!$this->getOrderingElementList()->countElements()) {
114  return false;
115  }
116 
117  return true;
118  }
119 
127  public function saveToDb($original_id = "")
128  {
129  global $DIC;
130  $ilDB = $DIC['ilDB'];
131 
135  parent::saveToDb($original_id);
136  }
137 
145  public function loadFromDb($question_id)
146  {
147  global $DIC;
148  $ilDB = $DIC['ilDB'];
149 
150  $result = $ilDB->queryF(
151  "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",
152  array("integer"),
153  array($question_id)
154  );
155  if ($result->numRows() == 1) {
156  $data = $ilDB->fetchAssoc($result);
157  $this->setId($question_id);
158  $this->setObjId($data["obj_fi"]);
159  $this->setTitle($data["title"]);
160  $this->setComment($data["description"]);
161  $this->setOriginalId($data["original_id"]);
162  $this->setAuthor($data["author"]);
163  $this->setNrOfTries($data['nr_of_tries']);
164  $this->setPoints($data["points"]);
165  $this->setOwner($data["owner"]);
166  include_once("./Services/RTE/classes/class.ilRTE.php");
167  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
168  $this->ordering_type = strlen($data["ordering_type"]) ? $data["ordering_type"] : OQ_TERMS;
169  $this->thumb_geometry = $data["thumb_geometry"];
170  $this->element_height = $data["element_height"];
171  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
172 
173  try {
177  }
178 
179  try {
180  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
181  } catch (ilTestQuestionPoolException $e) {
182  }
183  }
184 
185  $this->orderingElementList->setQuestionId($this->getId());
186  $this->orderingElementList->loadFromDb();
187 
188  parent::loadFromDb($question_id);
189  }
190 
196  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
197  {
198  if ($this->id <= 0) {
199  // The question has not been saved. It cannot be duplicated
200  return;
201  }
202  // duplicate the question in database
203  $this_id = $this->getId();
204  $thisObjId = $this->getObjId();
205 
206  $clone = $this;
207  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
209  $clone->id = -1;
210 
211  if ((int) $testObjId > 0) {
212  $clone->setObjId($testObjId);
213  }
214 
215  if ($title) {
216  $clone->setTitle($title);
217  }
218  if ($author) {
219  $clone->setAuthor($author);
220  }
221  if ($owner) {
222  $clone->setOwner($owner);
223  }
224  if ($for_test) {
225  $clone->saveToDb($original_id);
226  } else {
227  $clone->saveToDb();
228  }
229 
230  $clone->duplicateOrderlingElementList();
231 
232  // copy question page content
233  $clone->copyPageOfQuestion($this_id);
234  // copy XHTML media objects
235  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
236  // duplicate the image
237  $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
238 
239  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
240 
241  return $clone->id;
242  }
243 
244  protected function duplicateOrderlingElementList()
245  {
246  $this->getOrderingElementList()->setQuestionId($this->getId());
247  $this->getOrderingElementList()->distributeNewRandomIdentifiers();
248  $this->getOrderingElementList()->saveToDb();
249  }
250 
256  public function copyObject($target_questionpool_id, $title = "")
257  {
258  if ($this->id <= 0) {
259  // The question has not been saved. It cannot be duplicated
260  return;
261  }
262  // duplicate the question in database
263  $clone = $this;
264  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
266  $clone->id = -1;
267  $source_questionpool_id = $this->getObjId();
268  $clone->setObjId($target_questionpool_id);
269  if ($title) {
270  $clone->setTitle($title);
271  }
272 
273  $clone->saveToDb();
274 
275  // copy question page content
276  $clone->copyPageOfQuestion($original_id);
277  // copy XHTML media objects
278  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
279  // duplicate the image
280  $clone->duplicateImages($original_id, $source_questionpool_id, $clone->getId(), $target_questionpool_id);
281 
282  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
283 
284  return $clone->id;
285  }
286 
287  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
288  {
289  if ($this->id <= 0) {
290  // The question has not been saved. It cannot be duplicated
291  return;
292  }
293 
294  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
295 
296  $sourceQuestionId = $this->id;
297  $sourceParentId = $this->getObjId();
298 
299  // duplicate the question in database
300  $clone = $this;
301  $clone->id = -1;
302 
303  $clone->setObjId($targetParentId);
304 
305  if ($targetQuestionTitle) {
306  $clone->setTitle($targetQuestionTitle);
307  }
308 
309  $clone->saveToDb();
310  // copy question page content
311  $clone->copyPageOfQuestion($sourceQuestionId);
312  // copy XHTML media objects
313  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
314  // duplicate the image
315  $clone->duplicateImages($sourceQuestionId, $sourceParentId, $clone->getId(), $clone->getObjId());
316 
317  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
318 
319  return $clone->id;
320  }
321 
322  public function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
323  {
324  global $DIC;
325  $ilLog = $DIC['ilLog'];
326  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES) {
327  $imagepath_original = $this->getImagePath($src_question_id, $src_object_id);
328  $imagepath = $this->getImagePath($dest_question_id, $dest_object_id);
329 
330  if (!file_exists($imagepath)) {
331  ilUtil::makeDirParents($imagepath);
332  }
333  foreach ($this->getOrderingElementList() as $element) {
334  $filename = $element->getContent();
335  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
336  $ilLog->write("image could not be duplicated!!!!");
337  }
338  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
339  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
340  $ilLog->write("image thumbnail could not be duplicated!!!!");
341  }
342  }
343  }
344  }
345  }
346 
352  public function copyImages($question_id, $source_questionpool)
353  {
354  global $DIC;
355  $ilLog = $DIC['ilLog'];
356  if ($this->getOrderingType() == OQ_PICTURES) {
357  $imagepath = $this->getImagePath();
358  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
359  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
360  if (!file_exists($imagepath)) {
361  ilUtil::makeDirParents($imagepath);
362  }
363  foreach ($this->getOrderingElementList() as $element) {
364  $filename = $element->getContent();
365  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
366  $ilLog->write("Ordering Question image could not be copied: ${imagepath_original}${filename}");
367  }
368  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
369  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
370  $ilLog->write("Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
371  }
372  }
373  }
374  }
375  }
376 
385  {
386  $this->ordering_type = $ordering_type;
387  }
388 
396  public function getOrderingType()
397  {
398  return $this->ordering_type;
399  }
400 
401  public function isOrderingTypeNested()
402  {
403  return in_array($this->getOrderingType(), array(OQ_NESTED_TERMS, OQ_NESTED_PICTURES));
404  }
405 
406  public function isImageOrderingType()
407  {
408  return in_array($this->getOrderingType(), array(OQ_PICTURES, OQ_NESTED_PICTURES));
409  }
410 
412  {
413  return $this->getOrderingType() == OQ_PICTURES;
414  }
415 
422  public function getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex, $getUseIntermediateSolution = false)
423  {
424  if ($forceCorrectSolution || !$activeId || $passIndex === null) {
425  return $this->getOrderingElementList();
426  }
427 
428  $solutionValues = $this->getSolutionValues($activeId, $passIndex, !$getUseIntermediateSolution);
429 
430  if (!count($solutionValues)) {
431  return $this->getShuffledOrderingElementList();
432  }
433 
434  return $this->getSolutionOrderingElementList($this->fetchIndexedValuesFromValuePairs($solutionValues));
435  }
436 
447  {
448  if ($inputGUI->isPostSubmit($lastPost)) {
449  return $this->fetchSolutionListFromFormSubmissionData($lastPost);
450  }
451 
452  // hey: prevPassSolutions - pass will be always available from now on
453  #if( $pass === null && !ilObjTest::_getUsePreviousAnswers($activeId, true) )
454  #// condition looks strange? yes - keep it null when previous solutions not enabled (!)
455  #{
456  # $pass = ilObjTest::_getPass($activeId);
457  #}
458  // hey.
459 
460  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs(
461  // hey: prevPassSolutions - obsolete due to central check
462  $this->getTestOutputSolutions($activeId, $pass)
463  // hey.
464  );
465 
466  if (count($indexedSolutionValues)) {
467  return $this->getSolutionOrderingElementList($indexedSolutionValues);
468  }
469 
470  return $this->getShuffledOrderingElementList();
471  }
472 
479  {
480  $value2 = explode(':', $value2);
481 
482  $randomIdentifier = $value2[0];
483  $selectedPosition = $value1;
484  $selectedIndentation = $value2[1];
485 
486  $element = $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)->getClone();
487 
488  $element->setPosition($selectedPosition);
489  $element->setIndentation($selectedIndentation);
490 
491  return $element;
492  }
493 
500  {
501  $solutionIdentifier = $value1;
502  $selectedPosition = ($value2 - 1);
503  $selectedIndentation = 0;
504 
505  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($solutionIdentifier)->getClone();
506 
507  $element->setPosition($selectedPosition);
508  $element->setIndentation($selectedIndentation);
509 
510  return $element;
511  }
512 
518  public function getSolutionOrderingElementList($indexedSolutionValues)
519  {
520  $solutionOrderingList = new ilAssOrderingElementList();
521  $solutionOrderingList->setQuestionId($this->getId());
522 
523  foreach ($indexedSolutionValues as $value1 => $value2) {
524  if ($this->isOrderingTypeNested()) {
525  $element = $this->getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2);
526  } else {
527  $element = $this->getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2);
528  }
529 
530  $solutionOrderingList->addElement($element);
531  }
532 
533  if (!$this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($solutionOrderingList)) {
534  throw new ilTestQuestionPoolException('inconsistent solution values given');
535  }
536 
537  return $solutionOrderingList;
538  }
539 
546  {
547  $shuffledRandomIdentifierIndex = $this->getShuffler()->shuffle(
548  $this->getOrderingElementList()->getRandomIdentifierIndex()
549  );
550 
551  $shuffledElementList = $this->getOrderingElementList()->getClone();
552  $shuffledElementList->reorderByRandomIdentifiers($shuffledRandomIdentifierIndex);
553  $shuffledElementList->resetElementsIndentations();
554 
555  return $shuffledElementList;
556  }
557 
561  public function getOrderingElementList()
562  {
564  }
565 
570  {
571  $this->orderingElementList = $orderingElementList;
572  }
573 
579  public function moveAnswerUp($position)
580  {
581  if (!$this->getOrderingElementList()->elementExistByPosition($position)) {
582  return false;
583  }
584 
585  if ($this->getOrderingElementList()->isFirstElementPosition($position)) {
586  return false;
587  }
588 
589  $this->getOrderingElementList()->moveElementByPositions($position, $position - 1);
590  }
591 
597  public function moveAnswerDown($position)
598  {
599  if (!$this->getOrderingElementList()->elementExistByPosition($position)) {
600  return false;
601  }
602 
603  if ($this->getOrderingElementList()->isLastElementPosition($position)) {
604  return false;
605  }
606 
607  $this->getOrderingElementList()->moveElementByPositions($position, $position + 1);
608 
609  return true;
610  }
611 
618  public function getAnswer($index = 0)
619  {
620  if (!$this->getOrderingElementList()->elementExistByPosition($index)) {
621  return null;
622  }
623 
624  return $this->getOrderingElementList()->getElementByPosition($index);
625  }
626 
635  public function deleteAnswer($randomIdentifier)
636  {
637  $this->getOrderingElementList()->removeElement(
638  $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)
639  );
640  $this->getOrderingElementList()->saveToDb();
641  }
642 
650  public function getAnswerCount()
651  {
652  return $this->getOrderingElementList()->countElements();
653  }
654 
665  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
666  {
667  if ($returndetails) {
668  throw new ilTestException('return details not implemented for ' . __METHOD__);
669  }
670 
671  if (is_null($pass)) {
672  $pass = $this->getSolutionMaxPass($active_id);
673  }
674 
675  $solutionValuePairs = $this->getSolutionValues($active_id, $pass, $authorizedSolution);
676 
677  if (!count($solutionValuePairs)) {
678  return 0;
679  }
680 
681  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs($solutionValuePairs);
682  $solutionOrderingElementList = $this->getSolutionOrderingElementList($indexedSolutionValues);
683 
684  return $this->calculateReachedPointsForSolution($solutionOrderingElementList);
685  }
686 
688  {
689  if (!$previewSession->hasParticipantSolution()) {
690  return 0;
691  }
692 
693  $solutionOrderingElementList = unserialize(
694  $previewSession->getParticipantsSolution()
695  );
696 
697  $reachedPoints = $this->calculateReachedPointsForSolution($solutionOrderingElementList);
698  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
699 
700  return $this->ensureNonNegativePoints($reachedPoints);
701  }
702 
709  public function getMaximumPoints()
710  {
711  return $this->getPoints();
712  }
713 
714  /*
715  * Returns the encrypted save filename of a matching picture
716  * Images are saved with an encrypted filename to prevent users from
717  * cheating by guessing the solution from the image filename
718  *
719  * @param string $filename Original filename
720  * @return string Encrypted filename
721  */
723  {
724  $extension = "";
725  if (preg_match("/.*\\.(\\w+)$/", $filename, $matches)) {
726  $extension = $matches[1];
727  }
728  return md5($filename) . "." . $extension;
729  }
730 
731  protected function cleanImagefiles()
732  {
733  if ($this->getOrderingType() == OQ_PICTURES) {
734  if (@file_exists($this->getImagePath())) {
735  $contents = ilUtil::getDir($this->getImagePath());
736  foreach ($contents as $f) {
737  if (strcmp($f['type'], 'file') == 0) {
738  $found = false;
739  foreach ($this->getOrderingElementList() as $orderElement) {
740  if (strcmp($f['entry'], $orderElement->getContent()) == 0) {
741  $found = true;
742  }
743  if (strcmp($f['entry'], $this->getThumbPrefix() . $orderElement->getContent()) == 0) {
744  $found = true;
745  }
746  }
747  if (!$found) {
748  if (@file_exists($this->getImagePath() . $f['entry'])) {
749  @unlink($this->getImagePath() . $f['entry']);
750  }
751  }
752  }
753  }
754  }
755  } else {
756  if (@file_exists($this->getImagePath())) {
757  ilUtil::delDir($this->getImagePath());
758  }
759  }
760  }
761 
762  /*
763  * Deletes an imagefile from the system if the file is deleted manually
764  *
765  * @param string $filename Image file filename
766  * @return boolean Success
767  */
768  public function dropImageFile($imageFilename)
769  {
770  if (!strlen($imageFilename)) {
771  return false;
772  }
773 
774  $result = @unlink($this->getImagePath() . $imageFilename);
775  $result = $result & @unlink($this->getImagePath() . $this->getThumbPrefix() . $imageFilename);
776 
777  return $result;
778  }
779 
780  public function isImageFileStored($imageFilename)
781  {
782  if (!strlen($imageFilename)) {
783  return false;
784  }
785 
786  if (!file_exists($this->getImagePath() . $imageFilename)) {
787  return false;
788  }
789 
790  return is_file($this->getImagePath() . $imageFilename);
791  }
792 
793  public function isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement)
794  {
795  if (!$this->hasOrderingTypeUploadSupport()) {
796  return false;
797  }
798 
799  if (!$newElement->getContent()) {
800  return false;
801  }
802 
803  return $newElement->getContent() != $oldElement->getContent();
804  }
805 
814  public function storeImageFile($uploadFile, $targetFile)
815  {
816  if (!strlen($uploadFile)) {
817  return false;
818  }
819 
820  $this->ensureImagePathExists();
821 
822  // store file with hashed name
823 
824  if (!ilUtil::moveUploadedFile($uploadFile, $targetFile, $this->getImagePath() . $targetFile)) {
825  return false;
826  }
827 
828  return true;
829  }
830 
831  public function handleThumbnailCreation(ilAssOrderingElementList $elementList)
832  {
833  foreach ($elementList as $element) {
834  $this->createImageThumbnail($element);
835  }
836  }
837 
838  public function createImageThumbnail(ilAssOrderingElement $element)
839  {
840  if ($this->getThumbGeometry()) {
841  $imageFile = $this->getImagePath() . $element->getContent();
842  $thumbFile = $this->getImagePath() . $this->getThumbPrefix() . $element->getContent();
843 
844  ilUtil::convertImage($imageFile, $thumbFile, "JPEG", $this->getThumbGeometry());
845  }
846  }
847 
855  public function validateSolutionSubmit()
856  {
857  $submittedSolutionList = $this->getSolutionListFromPostSubmit();
858 
859  if (!$submittedSolutionList->hasElements()) {
860  return true;
861  }
862 
863  return $this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($submittedSolutionList);
864  }
865 
874  public function saveWorkingData($active_id, $pass = null, $authorized = true)
875  {
876  $entered_values = 0;
877 
878  if (is_null($pass)) {
879  include_once "./Modules/Test/classes/class.ilObjTest.php";
880  $pass = ilObjTest::_getPass($active_id);
881  }
882 
883  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(
884  function () use (&$entered_values, $active_id, $pass, $authorized) {
885  $this->removeCurrentSolution($active_id, $pass, $authorized);
886 
887  foreach ($this->getSolutionListFromPostSubmit() as $orderingElement) {
888  $value1 = $orderingElement->getStorageValue1($this->getOrderingType());
889  $value2 = $orderingElement->getStorageValue2($this->getOrderingType());
890 
891  $this->saveCurrentSolution($active_id, $pass, $value1, trim($value2), $authorized);
892 
893  $entered_values++;
894  }
895  }
896  );
897 
898  if ($entered_values) {
899  $this->log($active_id, 'log_user_entered_values');
900  } else {
901  $this->log($active_id, 'log_user_not_entered_values');
902  }
903 
904  return true;
905  }
906 
907  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
908  {
909  if ($this->validateSolutionSubmit()) {
910  $previewSession->setParticipantsSolution(serialize($this->getSolutionListFromPostSubmit()));
911  }
912  }
913 
914  public function saveAdditionalQuestionDataToDb()
915  {
917  global $DIC;
918  $ilDB = $DIC['ilDB'];
919 
920  // save additional data
921  $ilDB->manipulateF(
922  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
923  array( "integer" ),
924  array( $this->getId() )
925  );
926 
927  $ilDB->manipulateF(
928  "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, ordering_type, thumb_geometry, element_height)
929  VALUES (%s, %s, %s, %s)",
930  array( "integer", "text", "integer", "integer" ),
931  array(
932  $this->getId(),
933  $this->ordering_type,
934  $this->getThumbGeometry(),
935  ($this->getElementHeight() > 20) ? $this->getElementHeight() : null
936  )
937  );
938  }
939 
940  public function saveAnswerSpecificDataToDb()
941  {
942  $this->getOrderingElementList()->setQuestionId($this->getId());
943  $this->getOrderingElementList()->saveToDb();
944 
945  if ($this->hasOrderingTypeUploadSupport()) {
946  $this->rebuildThumbnails();
947  $this->cleanImagefiles();
948  }
949  }
950 
957  public function getQuestionType()
958  {
959  return "assOrderingQuestion";
960  }
961 
968  public function getAdditionalTableName()
969  {
970  return "qpl_qst_ordering";
971  }
972 
979  public function getAnswerTableName()
980  {
981  return "qpl_a_ordering";
982  }
983 
988  public function getRTETextWithMediaObjects()
989  {
990  $text = parent::getRTETextWithMediaObjects();
991 
992  foreach ($this->getOrderingElementList() as $orderingElement) {
993  $text .= $orderingElement->getContent();
994  }
995 
996  return $text;
997  }
998 
1003  public function getOrderElements()
1004  {
1005  return $this->getOrderingElementList()->getRandomIdentifierIndexedElements();
1006  }
1007 
1014  public function supportsJavascriptOutput()
1015  {
1016  return true;
1017  }
1018 
1019  public function supportsNonJsOutput()
1020  {
1021  return false;
1022  }
1023 
1027  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1028  {
1029  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1030 
1031  $solutions = $this->getSolutionValues($active_id, $pass);
1032  $sol = array();
1033  foreach ($solutions as $solution) {
1034  $sol[$solution["value1"]] = $solution["value2"];
1035  }
1036  asort($sol);
1037  $sol = array_keys($sol);
1038 
1039  $i = 1;
1040  foreach ($sol as $idx) {
1041  foreach ($solutions as $solution) {
1042  if ($solution["value1"] == $idx) {
1043  $worksheet->setCell($startrow + $i, 0, $solution["value2"]);
1044  }
1045  }
1046  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($idx);
1047  $worksheet->setCell($startrow + $i, 1, $element->getContent());
1048  $i++;
1049  }
1050 
1051  return $startrow + $i + 1;
1052  }
1053 
1054  /*
1055  * Get the thumbnail geometry
1056  *
1057  * @return integer Geometry
1058  */
1059  public function getThumbGeometry()
1060  {
1061  return $this->thumb_geometry;
1062  }
1063 
1064  public function getThumbSize()
1065  {
1066  return $this->getThumbGeometry();
1067  }
1068 
1069  /*
1070  * Set the thumbnail geometry
1071  *
1072  * @param integer $a_geometry Geometry
1073  */
1074  public function setThumbGeometry($a_geometry)
1075  {
1076  $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1077  }
1078 
1079  /*
1080  * Get the minimum element height
1081  *
1082  * @return integer Height
1083  */
1084  public function getElementHeight()
1085  {
1086  return $this->element_height;
1087  }
1088 
1089  /*
1090  * Set the minimum element height
1091  *
1092  * @param integer $a_height Height
1093  */
1094  public function setElementHeight($a_height)
1095  {
1096  $this->element_height = ($a_height < 20) ? "" : $a_height;
1097  }
1098 
1099  /*
1100  * Rebuild the thumbnail images with a new thumbnail size
1101  */
1102  public function rebuildThumbnails()
1103  {
1104  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1105  foreach ($this->getOrderElements() as $orderingElement) {
1106  $this->generateThumbForFile($this->getImagePath(), $orderingElement->getContent());
1107  }
1108  }
1109  }
1110 
1111  public function getThumbPrefix()
1112  {
1113  return "thumb.";
1114  }
1115 
1116  protected function generateThumbForFile($path, $file)
1117  {
1118  $filename = $path . $file;
1119  if (@file_exists($filename)) {
1120  $thumbpath = $path . $this->getThumbPrefix() . $file;
1121  $path_info = @pathinfo($filename);
1122  $ext = "";
1123  switch (strtoupper($path_info['extension'])) {
1124  case 'PNG':
1125  $ext = 'PNG';
1126  break;
1127  case 'GIF':
1128  $ext = 'GIF';
1129  break;
1130  default:
1131  $ext = 'JPEG';
1132  break;
1133  }
1134  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1135  }
1136  }
1137 
1141  public function toJSON()
1142  {
1143  include_once("./Services/RTE/classes/class.ilRTE.php");
1144  $result = array();
1145  $result['id'] = (int) $this->getId();
1146  $result['type'] = (string) $this->getQuestionType();
1147  $result['title'] = (string) $this->getTitle();
1148  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1149  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1150  $result['shuffle'] = (bool) true;
1151  $result['points'] = $this->getPoints();
1152  $result['feedback'] = array(
1153  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1154  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1155  );
1156  if ($this->getOrderingType() == OQ_PICTURES) {
1157  $result['path'] = $this->getImagePathWeb();
1158  }
1159 
1160  $counter = 1;
1161  $answers = array();
1162  foreach ($this->getOrderingElementList() as $orderingElement) {
1163  $answers[$counter] = $orderingElement->getContent();
1164  $counter++;
1165  }
1166  $answers = $this->getShuffler()->shuffle($answers);
1167  $arr = array();
1168  foreach ($answers as $order => $answer) {
1169  array_push($arr, array(
1170  "answertext" => (string) $answer,
1171  "order" => (int) $order
1172  ));
1173  }
1174  $result['answers'] = $arr;
1175 
1176  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1177  $result['mobs'] = $mobs;
1178 
1179  return json_encode($result);
1180  }
1181 
1187  {
1188  switch ($this->getOrderingType()) {
1189  case OQ_TERMS:
1190 
1191  return $this->buildOrderingTextsInputGui();
1192 
1193  case OQ_PICTURES:
1194 
1195  return $this->buildOrderingImagesInputGui();
1196 
1197  case OQ_NESTED_TERMS:
1198  case OQ_NESTED_PICTURES:
1199 
1200  return $this->buildNestedOrderingElementInputGui();
1201 
1202  default:
1203  throw new ilTestQuestionPoolException('unknown ordering mode');
1204  }
1205  }
1206 
1211  {
1212  switch (true) {
1213  case $formField instanceof ilAssNestedOrderingElementsInputGUI:
1214 
1215  $formField->setInteractionEnabled(true);
1216  $formField->setNestingEnabled($this->isOrderingTypeNested());
1217  break;
1218 
1219  case $formField instanceof ilAssOrderingTextsInputGUI:
1220  case $formField instanceof ilAssOrderingImagesInputGUI:
1221  default:
1222 
1223  $formField->setEditElementOccuranceEnabled(true);
1224  $formField->setEditElementOrderEnabled(true);
1225  }
1226 
1227  $formField->setRequired(true);
1228  }
1229 
1234  {
1235  $formField->setInfo($this->lng->txt('ordering_answer_sequence_info'));
1236  $formField->setTitle($this->lng->txt('answers'));
1237  }
1238 
1242  public function buildOrderingTextsInputGui()
1243  {
1244  $formDataConverter = $this->buildOrderingTextsFormDataConverter();
1245 
1246  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingTextsInputGUI.php';
1247 
1248  $orderingElementInput = new ilAssOrderingTextsInputGUI(
1249  $formDataConverter,
1250  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1251  );
1252 
1253  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1254 
1255  return $orderingElementInput;
1256  }
1257 
1262  {
1263  $formDataConverter = $this->buildOrderingImagesFormDataConverter();
1264 
1265  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingImagesInputGUI.php';
1266 
1267  $orderingElementInput = new ilAssOrderingImagesInputGUI(
1268  $formDataConverter,
1269  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1270  );
1271 
1272  $orderingElementInput->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1273  $orderingElementInput->setImageUploadCommand(self::ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG);
1274 
1275  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1276 
1277  return $orderingElementInput;
1278  }
1279 
1284  {
1285  $formDataConverter = $this->buildNestedOrderingFormDataConverter();
1286 
1287  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php';
1288 
1289  $orderingElementInput = new ilAssNestedOrderingElementsInputGUI(
1290  $formDataConverter,
1291  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1292  );
1293 
1294  $orderingElementInput->setUniquePrefix($this->getId());
1295  $orderingElementInput->setOrderingType($this->getOrderingType());
1296  $orderingElementInput->setElementImagePath($this->getImagePathWeb());
1297  $orderingElementInput->setThumbPrefix($this->getThumbPrefix());
1298 
1299  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1300 
1301  return $orderingElementInput;
1302  }
1303 
1309  {
1310  return $form->getItemByPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR)->getElementList($this->getId());
1311  }
1312 
1318  public function fetchSolutionListFromFormSubmissionData($userSolutionPost)
1319  {
1320  $orderingGUI = $this->buildNestedOrderingElementInputGui();
1322  $orderingGUI->setValueByArray($userSolutionPost);
1323 
1324  if (!$orderingGUI->checkInput()) {
1325  require_once 'Modules/Test/exceptions/class.ilTestException.php';
1326  throw new ilTestException('error on validating user solution post');
1327  }
1328 
1329  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssOrderingElementList.php';
1330  $solutionOrderingElementList = ilAssOrderingElementList::buildInstance($this->getId());
1331 
1332  $storedElementList = $this->getOrderingElementList();
1333 
1334  foreach ($orderingGUI->getElementList($this->getId()) as $submittedElement) {
1335  $solutionElement = $storedElementList->getElementByRandomIdentifier(
1336  $submittedElement->getRandomIdentifier()
1337  )->getClone();
1338 
1339  $solutionElement->setPosition($submittedElement->getPosition());
1340 
1341  if ($this->isOrderingTypeNested()) {
1342  $solutionElement->setIndentation($submittedElement->getIndentation());
1343  }
1344 
1345  $solutionOrderingElementList->addElement($solutionElement);
1346  }
1347 
1348  return $solutionOrderingElementList;
1349  }
1350 
1355 
1360  {
1361  if ($this->postSolutionOrderingElementList === null) {
1363  $this->postSolutionOrderingElementList = $list;
1364  }
1365 
1367  }
1368 
1372  public function getSolutionPostSubmit()
1373  {
1374  return $this->fetchSolutionSubmit($_POST);
1375  }
1376 
1382  protected function calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList)
1383  {
1384  $reachedPoints = $this->getPoints();
1385 
1386  foreach ($this->getOrderingElementList() as $correctElement) {
1387  $userElement = $solutionOrderingElementList->getElementByPosition($correctElement->getPosition());
1388 
1389  if (!$correctElement->isSameElement($userElement)) {
1390  $reachedPoints = 0;
1391  break;
1392  }
1393  }
1394 
1395  return $reachedPoints;
1396  }
1397 
1398  /***
1399  * @param object $child
1400  * @param integer $ordering_depth
1401  * @param bool $with_random_id
1402  */
1403  public function getLeveledOrdering()
1404  {
1405  return $this->leveled_ordering;
1406  }
1407 
1408  public function getOldLeveledOrdering()
1409  {
1410  global $DIC;
1411  $ilDB = $DIC['ilDB'];
1412 
1413  $res = $ilDB->queryF(
1414  'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY position ASC',
1415  array('integer'),
1416  array($this->getId())
1417  );
1418  while ($row = $ilDB->fetchAssoc($res)) {
1419  $this->old_ordering_depth[] = $row['depth'];
1420  }
1422  }
1423 
1424  /***
1425  * @param integer $a_random_id
1426  * @return integer
1427  */
1428  public function lookupSolutionOrderByRandomid($a_random_id)
1429  {
1430  global $DIC;
1431  $ilDB = $DIC['ilDB'];
1432 
1433  $res = $ilDB->queryF(
1434  'SELECT solution_key FROM qpl_a_ordering WHERE random_id = %s',
1435  array('integer'),
1436  array($a_random_id)
1437  );
1438  $row = $ilDB->fetchAssoc($res);
1439 
1440  return $row['solution_key'];
1441  }
1442 
1443  public function updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
1444  {
1445  global $DIC;
1446  $ilDB = $DIC['ilDB'];
1447 
1448  $ilDB->update(
1449  'qpl_a_ordering',
1450  array('solution_key' => array('integer', $a_index),
1451  'depth' => array('integer', $a_depth)),
1452  array('answertext' => array('text', $a_answer_text))
1453  );
1454 
1455 
1456  return true;
1457  }
1458 
1467  public function getOperators($expression)
1468  {
1469  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1471  }
1472 
1477  public function getExpressionTypes()
1478  {
1479  return array(
1484  );
1485  }
1486 
1495  public function getUserQuestionResult($active_id, $pass)
1496  {
1498  global $DIC;
1499  $ilDB = $DIC['ilDB'];
1500  $result = new ilUserQuestionResult($this, $active_id, $pass);
1501 
1502  $maxStep = $this->lookupMaxStep($active_id, $pass);
1503 
1504  if ($maxStep !== null) {
1505  $data = $ilDB->queryF(
1506  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY value1 ASC ",
1507  array("integer", "integer", "integer","integer"),
1508  array($active_id, $pass, $this->getId(), $maxStep)
1509  );
1510  } else {
1511  $data = $ilDB->queryF(
1512  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY value1 ASC ",
1513  array("integer", "integer", "integer"),
1514  array($active_id, $pass, $this->getId())
1515  );
1516  }
1517 
1518  $elements = array();
1519  while ($row = $ilDB->fetchAssoc($data)) {
1520  $newKey = explode(":", $row["value2"]);
1521 
1522  foreach ($this->getOrderingElementList() as $answer) {
1523  // Images nut supported
1524  if (!$this->isOrderingTypeNested()) {
1525  if ($answer->getSolutionIdentifier() == $row["value1"]) {
1526  $elements[$row["value2"]] = $answer->getSolutionIdentifier() + 1;
1527  break;
1528  }
1529  } else {
1530  if ($answer->getRandomIdentifier() == $newKey[0]) {
1531  $elements[$row["value1"]] = $answer->getSolutionIdentifier() + 1;
1532  break;
1533  }
1534  }
1535  }
1536  }
1537 
1538  ksort($elements);
1539 
1540  foreach (array_values($elements) as $element) {
1541  $result->addKeyValue($element, $element);
1542  }
1543 
1544  $points = $this->calculateReachedPoints($active_id, $pass);
1545  $max_points = $this->getMaximumPoints();
1546 
1547  $result->setReachedPercentage(($points / $max_points) * 100);
1548 
1549  return $result;
1550  }
1551 
1560  public function getAvailableAnswerOptions($index = null)
1561  {
1562  if ($index !== null) {
1563  return $this->getOrderingElementList()->getElementByPosition($index);
1564  }
1565 
1566  return $this->getOrderingElementList()->getElements();
1567  }
1568 
1572  protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1573  {
1574  parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1575  $this->duplicateImages($dupQuestionId, $dupParentObjId, $origQuestionId, $origParentObjId);
1576  }
1577 
1578  // fau: testNav - new function getTestQuestionConfig()
1583  // hey: refactored identifiers
1585  // hey.
1586  {
1587  // hey: refactored identifiers
1588  return parent::buildTestPresentationConfig()
1589  // hey.
1590  ->setIsUnchangedAnswerPossible(true)
1591  ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
1592  }
1593  // fau.
1594 
1595  protected function ensureImagePathExists()
1596  {
1597  if (!file_exists($this->getImagePath())) {
1599  }
1600  }
1601 
1605  public function fetchSolutionSubmit($formSubmissionDataStructure)
1606  {
1607  $solutionSubmit = array();
1608 
1609  if (isset($formSubmissionDataStructure['orderresult'])) {
1610  $orderresult = $formSubmissionDataStructure['orderresult'];
1611 
1612  if (strlen($orderresult)) {
1613  $orderarray = explode(":", $orderresult);
1614  $ordervalue = 1;
1615  foreach ($orderarray as $index) {
1616  $idmatch = null;
1617  if (preg_match("/id_(\\d+)/", $index, $idmatch)) {
1618  $randomid = $idmatch[1];
1619  foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1620  if ($answer->getRandomIdentifier() == $randomid) {
1621  $solutionSubmit[$answeridx] = $ordervalue;
1622  $ordervalue++;
1623  }
1624  }
1625  }
1626  }
1627  }
1628  } elseif ($this->getOrderingType() == OQ_NESTED_TERMS || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1629  $index = 0;
1630  foreach ($formSubmissionDataStructure['content'] as $randomId => $content) {
1631  $indentation = $formSubmissionDataStructure['indentation'];
1632 
1633  $value1 = $index++;
1634  $value2 = implode(':', array($randomId, $indentation));
1635 
1636  $solutionSubmit[$value1] = $value2;
1637  }
1638  } else {
1639  foreach ($formSubmissionDataStructure as $key => $value) {
1640  $matches = null;
1641  if (preg_match("/^order_(\d+)/", $key, $matches)) {
1642  if (!(preg_match("/initial_value_\d+/", $value))) {
1643  if (strlen($value)) {
1644  foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1645  if ($answer->getRandomIdentifier() == $matches[1]) {
1646  $solutionSubmit[$answeridx] = $value;
1647  }
1648  }
1649  }
1650  }
1651  }
1652  }
1653  }
1654 
1655  return $solutionSubmit;
1656  }
1657 
1662  {
1663  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingFormValuesObjectsConverter.php';
1664  $converter = new ilAssOrderingFormValuesObjectsConverter();
1665  $converter->setPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR);
1666 
1667  return $converter;
1668  }
1669 
1674  {
1675  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1677 
1678  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1679  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1680  $formDataConverter->setImageFsPath($this->getImagePath());
1681 
1682  if ($this->getThumbSize() && $this->getThumbPrefix()) {
1683  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1684  }
1685  return $formDataConverter;
1686  }
1687 
1692  {
1693  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1695  return $formDataConverter;
1696  }
1697 
1702  {
1703  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1705 
1706  if ($this->getOrderingType() == OQ_NESTED_PICTURES) {
1707  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1708  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1709 
1710  if ($this->getThumbSize() && $this->getThumbPrefix()) {
1711  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1712  }
1713  }
1714 
1715  return $formDataConverter;
1716  }
1717 }
duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
static makeDirParents($a_dir)
Create a new directory and all parent directories.
initOrderingElementAuthoringProperties(ilFormPropertyGUI $formField)
fetchSolutionListFromFormSubmissionData($userSolutionPost)
getId()
Gets the id of the assQuestion object.
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
getSolutionOrderingElementListForTestOutput(ilAssNestedOrderingElementsInputGUI $inputGUI, $lastPost, $activeId, $pass)
Class iQuestionCondition.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
$data
Definition: storeScorm.php:23
getItemByPostVar($a_post_var)
Get Item by POST variable.
calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList)
$result
getSolutionOrderingElementList($indexedSolutionValues)
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
This class represents a property form user interface.
getPoints()
Returns the maximum available points for the question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
fetchSolutionSubmit($formSubmissionDataStructure)
Abstract basic class which is to be extended by the concrete assessment question type classes...
isComplete()
Returns true, if a ordering question is complete for use.
getOrderingType()
Returns the ordering question type.
const OQ_NESTED_TERMS
initOrderingElementFormFieldLabels(ilFormPropertyGUI $formField)
ensureNonNegativePoints($points)
getQuestionType()
Returns the question type of the question.
getOrderElements()
Returns the answers array.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
setId($id=-1)
Sets the id of the assQuestion object.
copyObject($target_questionpool_id, $title="")
Copies an assOrderingQuestion object.
static buildInstance($questionId, $orderingElements=array())
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
{}
getImagePathWeb()
Returns the web image path for web accessable images of a question.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getAnswer($index=0)
Returns the ordering element from the given position.
getOperators($expression)
Get all available operations for a specific question.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setNrOfTries($a_nr_of_tries)
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
getObjId()
Get the object id of the container object.
isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement)
getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2)
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
Base Exception for all Exceptions relating to Modules/Test.
fetchIndexedValuesFromValuePairs(array $valuePairs)
$index
Definition: metadata.php:128
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
setInfo($a_info)
Set Information Text.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assOrderingQuestion.
validateSolutionSubmit()
Checks the data to be saved for consistency.
setAuthor($author="")
Sets the authors name of the assQuestion object.
getAuthor()
Gets 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.
getExpressionTypes()
Get all available expression types for a specific question.
foreach($_POST as $key=> $value) $res
const OQ_PICTURES
Ordering question constants.
$mobs
Class ilUserQuestionResult.
getAnswerTableName()
Returns the name of the answer table in the database.
log($active_id, $langVar)
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
deleteAnswer($randomIdentifier)
Deletes an answer with a given index.
setTitle($a_title)
Set Title.
Interface ilObjAnswerScoringAdjustable.
toJSON()
Returns a JSON representation of the question.
fetchSolutionListFromSubmittedForm(ilPropertyFormGUI $form)
saveToDb($original_id="")
Saves a assOrderingQuestion object to a database.
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $ordering_type=OQ_TERMS)
assOrderingQuestion constructor
getQuestion()
Gets the question string of the question object.
static convertImage( $a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex, $getUseIntermediateSolution=false)
createImageThumbnail(ilAssOrderingElement $element)
storeImageFile($uploadFile, $targetFile)
Sets the image file and uploads the image to the object&#39;s image directory.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
setOrderingElementList($orderingElementList)
$filename
Definition: buildRTE.php:89
getTestOutputSolutions($activeId, $pass)
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2)
const OQ_TERMS
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
setQuestion($question="")
Sets the question string of the question object.
This class represents a property in a property form.
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
__construct(Container $dic, ilPlugin $plugin)
const OQ_NESTED_PICTURES
global $ilDB
setOriginalId($original_id)
$DIC
Definition: xapitoken.php:46
Class for ordering questions.
updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
setLifecycle(ilAssQuestionLifecycle $lifecycle)
getTitle()
Gets the title string of the assQuestion object.
buildTestPresentationConfig()
Get the test question configuration.
handleThumbnailCreation(ilAssOrderingElementList $elementList)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
copyImages($question_id, $source_questionpool)
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.
loadFromDb($question_id)
Loads a assOrderingQuestion object from a database.
$_POST["username"]
setRequired($a_required)
Set Required.
setOrderingType($ordering_type=OQ_TERMS)
Sets the ordering question type.
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
$i
Definition: metadata.php:24
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
getAnswerCount()
Returns the number of answers.