ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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  ) {
85  parent::__construct($title, $comment, $author, $owner, $question);
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 {
174  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
175  } catch (ilTestQuestionPoolException $e) {
176  }
177  }
178 
179  $this->orderingElementList->setQuestionId($this->getId());
180  $this->orderingElementList->loadFromDb();
181 
182  parent::loadFromDb($question_id);
183  }
184 
190  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
191  {
192  if ($this->id <= 0) {
193  // The question has not been saved. It cannot be duplicated
194  return;
195  }
196  // duplicate the question in database
197  $this_id = $this->getId();
198  $thisObjId = $this->getObjId();
199 
200  $clone = $this;
201  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
203  $clone->id = -1;
204 
205  if ((int) $testObjId > 0) {
206  $clone->setObjId($testObjId);
207  }
208 
209  if ($title) {
210  $clone->setTitle($title);
211  }
212  if ($author) {
213  $clone->setAuthor($author);
214  }
215  if ($owner) {
216  $clone->setOwner($owner);
217  }
218  if ($for_test) {
219  $clone->saveToDb($original_id);
220  } else {
221  $clone->saveToDb();
222  }
223 
224  $clone->duplicateOrderlingElementList();
225 
226  // copy question page content
227  $clone->copyPageOfQuestion($this_id);
228  // copy XHTML media objects
229  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
230  // duplicate the image
231  $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
232 
233  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
234 
235  return $clone->id;
236  }
237 
238  protected function duplicateOrderlingElementList()
239  {
240  $this->getOrderingElementList()->setQuestionId($this->getId());
241  $this->getOrderingElementList()->distributeNewRandomIdentifiers();
242  $this->getOrderingElementList()->saveToDb();
243  }
244 
250  public function copyObject($target_questionpool_id, $title = "")
251  {
252  if ($this->id <= 0) {
253  // The question has not been saved. It cannot be duplicated
254  return;
255  }
256  // duplicate the question in database
257  $clone = $this;
258  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
260  $clone->id = -1;
261  $source_questionpool_id = $this->getObjId();
262  $clone->setObjId($target_questionpool_id);
263  if ($title) {
264  $clone->setTitle($title);
265  }
266 
267  $clone->saveToDb();
268 
269  // copy question page content
270  $clone->copyPageOfQuestion($original_id);
271  // copy XHTML media objects
272  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
273  // duplicate the image
274  $clone->duplicateImages($original_id, $source_questionpool_id, $clone->getId(), $target_questionpool_id);
275 
276  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
277 
278  return $clone->id;
279  }
280 
281  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
282  {
283  if ($this->id <= 0) {
284  // The question has not been saved. It cannot be duplicated
285  return;
286  }
287 
288  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
289 
290  $sourceQuestionId = $this->id;
291  $sourceParentId = $this->getObjId();
292 
293  // duplicate the question in database
294  $clone = $this;
295  $clone->id = -1;
296 
297  $clone->setObjId($targetParentId);
298 
299  if ($targetQuestionTitle) {
300  $clone->setTitle($targetQuestionTitle);
301  }
302 
303  $clone->saveToDb();
304  // copy question page content
305  $clone->copyPageOfQuestion($sourceQuestionId);
306  // copy XHTML media objects
307  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
308  // duplicate the image
309  $clone->duplicateImages($sourceQuestionId, $sourceParentId, $clone->getId(), $clone->getObjId());
310 
311  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
312 
313  return $clone->id;
314  }
315 
316  public function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
317  {
318  global $DIC;
319  $ilLog = $DIC['ilLog'];
320  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES) {
321  $imagepath_original = $this->getImagePath($src_question_id, $src_object_id);
322  $imagepath = $this->getImagePath($dest_question_id, $dest_object_id);
323 
324  if (!file_exists($imagepath)) {
325  ilUtil::makeDirParents($imagepath);
326  }
327  foreach ($this->getOrderingElementList() as $element) {
328  $filename = $element->getContent();
329  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
330  $ilLog->write("image could not be duplicated!!!!");
331  }
332  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
333  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
334  $ilLog->write("image thumbnail could not be duplicated!!!!");
335  }
336  }
337  }
338  }
339  }
340 
346  public function copyImages($question_id, $source_questionpool)
347  {
348  global $DIC;
349  $ilLog = $DIC['ilLog'];
350  if ($this->getOrderingType() == OQ_PICTURES) {
351  $imagepath = $this->getImagePath();
352  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
353  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
354  if (!file_exists($imagepath)) {
355  ilUtil::makeDirParents($imagepath);
356  }
357  foreach ($this->getOrderingElementList() as $element) {
358  $filename = $element->getContent();
359  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
360  $ilLog->write("Ordering Question image could not be copied: ${imagepath_original}${filename}");
361  }
362  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
363  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
364  $ilLog->write("Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
365  }
366  }
367  }
368  }
369  }
370 
379  {
380  $this->ordering_type = $ordering_type;
381  }
382 
390  public function getOrderingType()
391  {
392  return $this->ordering_type;
393  }
394 
395  public function isOrderingTypeNested()
396  {
397  return in_array($this->getOrderingType(), array(OQ_NESTED_TERMS, OQ_NESTED_PICTURES));
398  }
399 
400  public function isImageOrderingType()
401  {
402  return in_array($this->getOrderingType(), array(OQ_PICTURES, OQ_NESTED_PICTURES));
403  }
404 
406  {
407  return $this->getOrderingType() == OQ_PICTURES;
408  }
409 
416  public function getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex, $getUseIntermediateSolution = false)
417  {
418  if ($forceCorrectSolution || !$activeId || $passIndex === null) {
419  return $this->getOrderingElementList();
420  }
421 
422  $solutionValues = $this->getSolutionValues($activeId, $passIndex, !$getUseIntermediateSolution);
423 
424  if (!count($solutionValues)) {
425  return $this->getShuffledOrderingElementList();
426  }
427 
428  return $this->getSolutionOrderingElementList($this->fetchIndexedValuesFromValuePairs($solutionValues));
429  }
430 
441  {
442  if ($inputGUI->isPostSubmit($lastPost)) {
443  return $this->fetchSolutionListFromFormSubmissionData($lastPost);
444  }
445 
446  // hey: prevPassSolutions - pass will be always available from now on
447  #if( $pass === null && !ilObjTest::_getUsePreviousAnswers($activeId, true) )
448  #// condition looks strange? yes - keep it null when previous solutions not enabled (!)
449  #{
450  # $pass = ilObjTest::_getPass($activeId);
451  #}
452  // hey.
453 
454  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs(
455  // hey: prevPassSolutions - obsolete due to central check
456  $this->getTestOutputSolutions($activeId, $pass)
457  // hey.
458  );
459 
460  if (count($indexedSolutionValues)) {
461  return $this->getSolutionOrderingElementList($indexedSolutionValues);
462  }
463 
464  return $this->getShuffledOrderingElementList();
465  }
466 
473  {
474  $value2 = explode(':', $value2);
475 
476  $randomIdentifier = $value2[0];
477  $selectedPosition = $value1;
478  $selectedIndentation = $value2[1];
479 
480  $element = $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)->getClone();
481 
482  $element->setPosition($selectedPosition);
483  $element->setIndentation($selectedIndentation);
484 
485  return $element;
486  }
487 
494  {
495  $solutionIdentifier = $value1;
496  $selectedPosition = ($value2 - 1);
497  $selectedIndentation = 0;
498 
499  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($solutionIdentifier)->getClone();
500 
501  $element->setPosition($selectedPosition);
502  $element->setIndentation($selectedIndentation);
503 
504  return $element;
505  }
506 
512  public function getSolutionOrderingElementList($indexedSolutionValues)
513  {
514  $solutionOrderingList = new ilAssOrderingElementList();
515  $solutionOrderingList->setQuestionId($this->getId());
516 
517  foreach ($indexedSolutionValues as $value1 => $value2) {
518  if ($this->isOrderingTypeNested()) {
519  $element = $this->getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2);
520  } else {
521  $element = $this->getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2);
522  }
523 
524  $solutionOrderingList->addElement($element);
525  }
526 
527  if (!$this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($solutionOrderingList)) {
528  throw new ilTestQuestionPoolException('inconsistent solution values given');
529  }
530 
531  return $solutionOrderingList;
532  }
533 
540  {
541  $shuffledRandomIdentifierIndex = $this->getShuffler()->shuffle(
542  $this->getOrderingElementList()->getRandomIdentifierIndex()
543  );
544 
545  $shuffledElementList = $this->getOrderingElementList()->getClone();
546  $shuffledElementList->reorderByRandomIdentifiers($shuffledRandomIdentifierIndex);
547  $shuffledElementList->resetElementsIndentations();
548 
549  return $shuffledElementList;
550  }
551 
555  public function getOrderingElementList()
556  {
558  }
559 
564  {
565  $this->orderingElementList = $orderingElementList;
566  }
567 
573  public function moveAnswerUp($position)
574  {
575  if (!$this->getOrderingElementList()->elementExistByPosition($position)) {
576  return false;
577  }
578 
579  if ($this->getOrderingElementList()->isFirstElementPosition($position)) {
580  return false;
581  }
582 
583  $this->getOrderingElementList()->moveElementByPositions($position, $position - 1);
584  }
585 
591  public function moveAnswerDown($position)
592  {
593  if (!$this->getOrderingElementList()->elementExistByPosition($position)) {
594  return false;
595  }
596 
597  if ($this->getOrderingElementList()->isLastElementPosition($position)) {
598  return false;
599  }
600 
601  $this->getOrderingElementList()->moveElementByPositions($position, $position + 1);
602 
603  return true;
604  }
605 
612  public function getAnswer($index = 0)
613  {
614  if (!$this->getOrderingElementList()->elementExistByPosition($index)) {
615  return null;
616  }
617 
618  return $this->getOrderingElementList()->getElementByPosition($index);
619  }
620 
629  public function deleteAnswer($randomIdentifier)
630  {
631  $this->getOrderingElementList()->removeElement(
632  $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)
633  );
634  $this->getOrderingElementList()->saveToDb();
635  }
636 
644  public function getAnswerCount()
645  {
646  return $this->getOrderingElementList()->countElements();
647  }
648 
659  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
660  {
661  if ($returndetails) {
662  throw new ilTestException('return details not implemented for ' . __METHOD__);
663  }
664 
665  if (is_null($pass)) {
666  $pass = $this->getSolutionMaxPass($active_id);
667  }
668 
669  $solutionValuePairs = $this->getSolutionValues($active_id, $pass, $authorizedSolution);
670 
671  if (!count($solutionValuePairs)) {
672  return 0;
673  }
674 
675  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs($solutionValuePairs);
676  $solutionOrderingElementList = $this->getSolutionOrderingElementList($indexedSolutionValues);
677 
678  return $this->calculateReachedPointsForSolution($solutionOrderingElementList);
679  }
680 
682  {
683  if (!$previewSession->hasParticipantSolution()) {
684  return 0;
685  }
686 
687  $solutionOrderingElementList = unserialize(
688  $previewSession->getParticipantsSolution()
689  );
690 
691  $reachedPoints = $this->calculateReachedPointsForSolution($solutionOrderingElementList);
692  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
693 
694  return $this->ensureNonNegativePoints($reachedPoints);
695  }
696 
703  public function getMaximumPoints()
704  {
705  return $this->getPoints();
706  }
707 
708  /*
709  * Returns the encrypted save filename of a matching picture
710  * Images are saved with an encrypted filename to prevent users from
711  * cheating by guessing the solution from the image filename
712  *
713  * @param string $filename Original filename
714  * @return string Encrypted filename
715  */
717  {
718  $extension = "";
719  if (preg_match("/.*\\.(\\w+)$/", $filename, $matches)) {
720  $extension = $matches[1];
721  }
722  return md5($filename) . "." . $extension;
723  }
724 
725  protected function cleanImagefiles()
726  {
727  if ($this->getOrderingType() == OQ_PICTURES) {
728  if (@file_exists($this->getImagePath())) {
729  $contents = ilUtil::getDir($this->getImagePath());
730  foreach ($contents as $f) {
731  if (strcmp($f['type'], 'file') == 0) {
732  $found = false;
733  foreach ($this->getOrderingElementList() as $orderElement) {
734  if (strcmp($f['entry'], $orderElement->getContent()) == 0) {
735  $found = true;
736  }
737  if (strcmp($f['entry'], $this->getThumbPrefix() . $orderElement->getContent()) == 0) {
738  $found = true;
739  }
740  }
741  if (!$found) {
742  if (@file_exists($this->getImagePath() . $f['entry'])) {
743  @unlink($this->getImagePath() . $f['entry']);
744  }
745  }
746  }
747  }
748  }
749  } else {
750  if (@file_exists($this->getImagePath())) {
751  ilUtil::delDir($this->getImagePath());
752  }
753  }
754  }
755 
756  /*
757  * Deletes an imagefile from the system if the file is deleted manually
758  *
759  * @param string $filename Image file filename
760  * @return boolean Success
761  */
762  public function dropImageFile($imageFilename)
763  {
764  if (!strlen($imageFilename)) {
765  return false;
766  }
767 
768  $result = @unlink($this->getImagePath() . $imageFilename);
769  $result = $result & @unlink($this->getImagePath() . $this->getThumbPrefix() . $imageFilename);
770 
771  return $result;
772  }
773 
774  public function isImageFileStored($imageFilename)
775  {
776  if (!strlen($imageFilename)) {
777  return false;
778  }
779 
780  if (!file_exists($this->getImagePath() . $imageFilename)) {
781  return false;
782  }
783 
784  return is_file($this->getImagePath() . $imageFilename);
785  }
786 
787  public function isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement)
788  {
789  if (!$this->hasOrderingTypeUploadSupport()) {
790  return false;
791  }
792 
793  if (!$newElement->getContent()) {
794  return false;
795  }
796 
797  return $newElement->getContent() != $oldElement->getContent();
798  }
799 
808  public function storeImageFile($uploadFile, $targetFile)
809  {
810  if (!strlen($uploadFile)) {
811  return false;
812  }
813 
814  $this->ensureImagePathExists();
815 
816  // store file with hashed name
817 
818  if (!ilUtil::moveUploadedFile($uploadFile, $targetFile, $this->getImagePath() . $targetFile)) {
819  return false;
820  }
821 
822  return true;
823  }
824 
825  public function handleThumbnailCreation(ilAssOrderingElementList $elementList)
826  {
827  foreach ($elementList as $element) {
828  $this->createImageThumbnail($element);
829  }
830  }
831 
832  public function createImageThumbnail(ilAssOrderingElement $element)
833  {
834  if ($this->getThumbGeometry()) {
835  $imageFile = $this->getImagePath() . $element->getContent();
836  $thumbFile = $this->getImagePath() . $this->getThumbPrefix() . $element->getContent();
837 
838  ilUtil::convertImage($imageFile, $thumbFile, "JPEG", $this->getThumbGeometry());
839  }
840  }
841 
849  public function validateSolutionSubmit()
850  {
851  $submittedSolutionList = $this->getSolutionListFromPostSubmit();
852 
853  if (!$submittedSolutionList->hasElements()) {
854  return true;
855  }
856 
857  return $this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($submittedSolutionList);
858  }
859 
868  public function saveWorkingData($active_id, $pass = null, $authorized = true)
869  {
870  $entered_values = 0;
871 
872  if (is_null($pass)) {
873  include_once "./Modules/Test/classes/class.ilObjTest.php";
874  $pass = ilObjTest::_getPass($active_id);
875  }
876 
877  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(
878  function () use (&$entered_values, $active_id, $pass, $authorized) {
879  $this->removeCurrentSolution($active_id, $pass, $authorized);
880 
881  foreach ($this->getSolutionListFromPostSubmit() as $orderingElement) {
882  $value1 = $orderingElement->getStorageValue1($this->getOrderingType());
883  $value2 = $orderingElement->getStorageValue2($this->getOrderingType());
884 
885  $this->saveCurrentSolution($active_id, $pass, $value1, trim($value2), $authorized);
886 
887  $entered_values++;
888  }
889  }
890  );
891 
892  if ($entered_values) {
893  $this->log($active_id, 'log_user_entered_values');
894  } else {
895  $this->log($active_id, 'log_user_not_entered_values');
896  }
897 
898  return true;
899  }
900 
901  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
902  {
903  if ($this->validateSolutionSubmit()) {
904  $previewSession->setParticipantsSolution(serialize($this->getSolutionListFromPostSubmit()));
905  }
906  }
907 
908  public function saveAdditionalQuestionDataToDb()
909  {
911  global $DIC;
912  $ilDB = $DIC['ilDB'];
913 
914  // save additional data
915  $ilDB->manipulateF(
916  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
917  array( "integer" ),
918  array( $this->getId() )
919  );
920 
921  $ilDB->manipulateF(
922  "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, ordering_type, thumb_geometry, element_height)
923  VALUES (%s, %s, %s, %s)",
924  array( "integer", "text", "integer", "integer" ),
925  array(
926  $this->getId(),
927  $this->ordering_type,
928  $this->getThumbGeometry(),
929  ($this->getElementHeight() > 20) ? $this->getElementHeight() : null
930  )
931  );
932  }
933 
934  public function saveAnswerSpecificDataToDb()
935  {
936  $this->getOrderingElementList()->setQuestionId($this->getId());
937  $this->getOrderingElementList()->saveToDb();
938 
939  if ($this->hasOrderingTypeUploadSupport()) {
940  $this->rebuildThumbnails();
941  $this->cleanImagefiles();
942  }
943  }
944 
951  public function getQuestionType()
952  {
953  return "assOrderingQuestion";
954  }
955 
962  public function getAdditionalTableName()
963  {
964  return "qpl_qst_ordering";
965  }
966 
973  public function getAnswerTableName()
974  {
975  return "qpl_a_ordering";
976  }
977 
982  public function getRTETextWithMediaObjects()
983  {
984  $text = parent::getRTETextWithMediaObjects();
985 
986  foreach ($this->getOrderingElementList() as $orderingElement) {
987  $text .= $orderingElement->getContent();
988  }
989 
990  return $text;
991  }
992 
997  public function getOrderElements()
998  {
999  return $this->getOrderingElementList()->getRandomIdentifierIndexedElements();
1000  }
1001 
1008  public function supportsJavascriptOutput()
1009  {
1010  return true;
1011  }
1012 
1013  public function supportsNonJsOutput()
1014  {
1015  return false;
1016  }
1017 
1021  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1022  {
1023  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1024 
1025  $solutions = $this->getSolutionValues($active_id, $pass);
1026  $sol = array();
1027  foreach ($solutions as $solution) {
1028  $sol[$solution["value1"]] = $solution["value2"];
1029  }
1030  asort($sol);
1031  $sol = array_keys($sol);
1032 
1033  $i = 1;
1034  foreach ($sol as $idx) {
1035  foreach ($solutions as $solution) {
1036  if ($solution["value1"] == $idx) {
1037  $worksheet->setCell($startrow + $i, 0, $solution["value2"]);
1038  }
1039  }
1040  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($idx);
1041  $worksheet->setCell($startrow + $i, 1, $element->getContent());
1042  $i++;
1043  }
1044 
1045  return $startrow + $i + 1;
1046  }
1047 
1048  /*
1049  * Get the thumbnail geometry
1050  *
1051  * @return integer Geometry
1052  */
1053  public function getThumbGeometry()
1054  {
1055  return $this->thumb_geometry;
1056  }
1057 
1058  public function getThumbSize()
1059  {
1060  return $this->getThumbGeometry();
1061  }
1062 
1063  /*
1064  * Set the thumbnail geometry
1065  *
1066  * @param integer $a_geometry Geometry
1067  */
1068  public function setThumbGeometry($a_geometry)
1069  {
1070  $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1071  }
1072 
1073  /*
1074  * Get the minimum element height
1075  *
1076  * @return integer Height
1077  */
1078  public function getElementHeight()
1079  {
1080  return $this->element_height;
1081  }
1082 
1083  /*
1084  * Set the minimum element height
1085  *
1086  * @param integer $a_height Height
1087  */
1088  public function setElementHeight($a_height)
1089  {
1090  $this->element_height = ($a_height < 20) ? "" : $a_height;
1091  }
1092 
1093  /*
1094  * Rebuild the thumbnail images with a new thumbnail size
1095  */
1096  public function rebuildThumbnails()
1097  {
1098  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1099  foreach ($this->getOrderElements() as $orderingElement) {
1100  $this->generateThumbForFile($this->getImagePath(), $orderingElement->getContent());
1101  }
1102  }
1103  }
1104 
1105  public function getThumbPrefix()
1106  {
1107  return "thumb.";
1108  }
1109 
1110  protected function generateThumbForFile($path, $file)
1111  {
1112  $filename = $path . $file;
1113  if (@file_exists($filename)) {
1114  $thumbpath = $path . $this->getThumbPrefix() . $file;
1115  $path_info = @pathinfo($filename);
1116  $ext = "";
1117  switch (strtoupper($path_info['extension'])) {
1118  case 'PNG':
1119  $ext = 'PNG';
1120  break;
1121  case 'GIF':
1122  $ext = 'GIF';
1123  break;
1124  default:
1125  $ext = 'JPEG';
1126  break;
1127  }
1128  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1129  }
1130  }
1131 
1135  public function toJSON()
1136  {
1137  include_once("./Services/RTE/classes/class.ilRTE.php");
1138  $result = array();
1139  $result['id'] = (int) $this->getId();
1140  $result['type'] = (string) $this->getQuestionType();
1141  $result['title'] = (string) $this->getTitle();
1142  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1143  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1144  $result['shuffle'] = (bool) true;
1145  $result['points'] = $this->getPoints();
1146  $result['feedback'] = array(
1147  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1148  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1149  );
1150  if ($this->getOrderingType() == OQ_PICTURES) {
1151  $result['path'] = $this->getImagePathWeb();
1152  }
1153 
1154  $counter = 1;
1155  $answers = array();
1156  foreach ($this->getOrderingElementList() as $orderingElement) {
1157  $answers[$counter] = $orderingElement->getContent();
1158  $counter++;
1159  }
1160  $answers = $this->getShuffler()->shuffle($answers);
1161  $arr = array();
1162  foreach ($answers as $order => $answer) {
1163  array_push($arr, array(
1164  "answertext" => (string) $answer,
1165  "order" => (int) $order
1166  ));
1167  }
1168  $result['answers'] = $arr;
1169 
1170  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1171  $result['mobs'] = $mobs;
1172 
1173  return json_encode($result);
1174  }
1175 
1181  {
1182  switch ($this->getOrderingType()) {
1183  case OQ_TERMS:
1184 
1185  return $this->buildOrderingTextsInputGui();
1186 
1187  case OQ_PICTURES:
1188 
1189  return $this->buildOrderingImagesInputGui();
1190 
1191  case OQ_NESTED_TERMS:
1192  case OQ_NESTED_PICTURES:
1193 
1194  return $this->buildNestedOrderingElementInputGui();
1195 
1196  default:
1197  throw new ilTestQuestionPoolException('unknown ordering mode');
1198  }
1199  }
1200 
1205  {
1206  switch (true) {
1207  case $formField instanceof ilAssNestedOrderingElementsInputGUI:
1208 
1209  $formField->setInteractionEnabled(true);
1210  $formField->setNestingEnabled($this->isOrderingTypeNested());
1211  break;
1212 
1213  case $formField instanceof ilAssOrderingTextsInputGUI:
1214  case $formField instanceof ilAssOrderingImagesInputGUI:
1215  default:
1216 
1217  $formField->setEditElementOccuranceEnabled(true);
1218  $formField->setEditElementOrderEnabled(true);
1219  }
1220 
1221  $formField->setRequired(true);
1222  }
1223 
1228  {
1229  $formField->setInfo($this->lng->txt('ordering_answer_sequence_info'));
1230  $formField->setTitle($this->lng->txt('answers'));
1231  }
1232 
1236  public function buildOrderingTextsInputGui()
1237  {
1238  $formDataConverter = $this->buildOrderingTextsFormDataConverter();
1239 
1240  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingTextsInputGUI.php';
1241 
1242  $orderingElementInput = new ilAssOrderingTextsInputGUI(
1243  $formDataConverter,
1244  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1245  );
1246 
1247  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1248 
1249  return $orderingElementInput;
1250  }
1251 
1256  {
1257  $formDataConverter = $this->buildOrderingImagesFormDataConverter();
1258 
1259  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingImagesInputGUI.php';
1260 
1261  $orderingElementInput = new ilAssOrderingImagesInputGUI(
1262  $formDataConverter,
1263  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1264  );
1265 
1266  $orderingElementInput->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1267  $orderingElementInput->setImageUploadCommand(self::ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG);
1268 
1269  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1270 
1271  return $orderingElementInput;
1272  }
1273 
1278  {
1279  $formDataConverter = $this->buildNestedOrderingFormDataConverter();
1280 
1281  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php';
1282 
1283  $orderingElementInput = new ilAssNestedOrderingElementsInputGUI(
1284  $formDataConverter,
1285  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1286  );
1287 
1288  $orderingElementInput->setUniquePrefix($this->getId());
1289  $orderingElementInput->setOrderingType($this->getOrderingType());
1290  $orderingElementInput->setElementImagePath($this->getImagePathWeb());
1291  $orderingElementInput->setThumbPrefix($this->getThumbPrefix());
1292 
1293  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1294 
1295  return $orderingElementInput;
1296  }
1297 
1303  {
1304  return $form->getItemByPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR)->getElementList($this->getId());
1305  }
1306 
1312  public function fetchSolutionListFromFormSubmissionData($userSolutionPost)
1313  {
1314  $orderingGUI = $this->buildNestedOrderingElementInputGui();
1316  $orderingGUI->setValueByArray($userSolutionPost);
1317 
1318  if (!$orderingGUI->checkInput()) {
1319  require_once 'Modules/Test/exceptions/class.ilTestException.php';
1320  throw new ilTestException('error on validating user solution post');
1321  }
1322 
1323  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssOrderingElementList.php';
1324  $solutionOrderingElementList = ilAssOrderingElementList::buildInstance($this->getId());
1325 
1326  $storedElementList = $this->getOrderingElementList();
1327 
1328  foreach ($orderingGUI->getElementList($this->getId()) as $submittedElement) {
1329  $solutionElement = $storedElementList->getElementByRandomIdentifier(
1330  $submittedElement->getRandomIdentifier()
1331  )->getClone();
1332 
1333  $solutionElement->setPosition($submittedElement->getPosition());
1334 
1335  if ($this->isOrderingTypeNested()) {
1336  $solutionElement->setIndentation($submittedElement->getIndentation());
1337  }
1338 
1339  $solutionOrderingElementList->addElement($solutionElement);
1340  }
1341 
1342  return $solutionOrderingElementList;
1343  }
1344 
1349 
1354  {
1355  if ($this->postSolutionOrderingElementList === null) {
1357  $this->postSolutionOrderingElementList = $list;
1358  }
1359 
1361  }
1362 
1366  public function getSolutionPostSubmit()
1367  {
1368  return $this->fetchSolutionSubmit($_POST);
1369  }
1370 
1376  protected function calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList)
1377  {
1378  $reachedPoints = $this->getPoints();
1379 
1380  foreach ($this->getOrderingElementList() as $correctElement) {
1381  $userElement = $solutionOrderingElementList->getElementByPosition($correctElement->getPosition());
1382 
1383  if (!$correctElement->isSameElement($userElement)) {
1384  $reachedPoints = 0;
1385  break;
1386  }
1387  }
1388 
1389  return $reachedPoints;
1390  }
1391 
1392  /***
1393  * @param object $child
1394  * @param integer $ordering_depth
1395  * @param bool $with_random_id
1396  */
1397  public function getLeveledOrdering()
1398  {
1399  return $this->leveled_ordering;
1400  }
1401 
1402  public function getOldLeveledOrdering()
1403  {
1404  global $DIC;
1405  $ilDB = $DIC['ilDB'];
1406 
1407  $res = $ilDB->queryF(
1408  'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY position ASC',
1409  array('integer'),
1410  array($this->getId())
1411  );
1412  while ($row = $ilDB->fetchAssoc($res)) {
1413  $this->old_ordering_depth[] = $row['depth'];
1414  }
1416  }
1417 
1418  /***
1419  * @param integer $a_random_id
1420  * @return integer
1421  */
1422  public function lookupSolutionOrderByRandomid($a_random_id)
1423  {
1424  global $DIC;
1425  $ilDB = $DIC['ilDB'];
1426 
1427  $res = $ilDB->queryF(
1428  'SELECT solution_key FROM qpl_a_ordering WHERE random_id = %s',
1429  array('integer'),
1430  array($a_random_id)
1431  );
1432  $row = $ilDB->fetchAssoc($res);
1433 
1434  return $row['solution_key'];
1435  }
1436 
1437  public function updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
1438  {
1439  global $DIC;
1440  $ilDB = $DIC['ilDB'];
1441 
1442  $ilDB->update(
1443  'qpl_a_ordering',
1444  array('solution_key' => array('integer', $a_index),
1445  'depth' => array('integer', $a_depth)),
1446  array('answertext' => array('text', $a_answer_text))
1447  );
1448 
1449 
1450  return true;
1451  }
1452 
1461  public function getOperators($expression)
1462  {
1463  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1465  }
1466 
1471  public function getExpressionTypes()
1472  {
1473  return array(
1478  );
1479  }
1480 
1489  public function getUserQuestionResult($active_id, $pass)
1490  {
1492  global $DIC;
1493  $ilDB = $DIC['ilDB'];
1494  $result = new ilUserQuestionResult($this, $active_id, $pass);
1495 
1496  $maxStep = $this->lookupMaxStep($active_id, $pass);
1497 
1498  if ($maxStep !== null) {
1499  $data = $ilDB->queryF(
1500  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY value1 ASC ",
1501  array("integer", "integer", "integer","integer"),
1502  array($active_id, $pass, $this->getId(), $maxStep)
1503  );
1504  } else {
1505  $data = $ilDB->queryF(
1506  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY value1 ASC ",
1507  array("integer", "integer", "integer"),
1508  array($active_id, $pass, $this->getId())
1509  );
1510  }
1511 
1512  $elements = array();
1513  while ($row = $ilDB->fetchAssoc($data)) {
1514  $newKey = explode(":", $row["value2"]);
1515 
1516  foreach ($this->getOrderingElementList() as $answer) {
1517  // Images nut supported
1518  if (!$this->isOrderingTypeNested()) {
1519  if ($answer->getSolutionIdentifier() == $row["value1"]) {
1520  $elements[$row["value2"]] = $answer->getSolutionIdentifier() + 1;
1521  break;
1522  }
1523  } else {
1524  if ($answer->getRandomIdentifier() == $newKey[0]) {
1525  $elements[$row["value1"]] = $answer->getSolutionIdentifier() + 1;
1526  break;
1527  }
1528  }
1529  }
1530  }
1531 
1532  ksort($elements);
1533 
1534  foreach (array_values($elements) as $element) {
1535  $result->addKeyValue($element, $element);
1536  }
1537 
1538  $points = $this->calculateReachedPoints($active_id, $pass);
1539  $max_points = $this->getMaximumPoints();
1540 
1541  $result->setReachedPercentage(($points / $max_points) * 100);
1542 
1543  return $result;
1544  }
1545 
1554  public function getAvailableAnswerOptions($index = null)
1555  {
1556  if ($index !== null) {
1557  return $this->getOrderingElementList()->getElementByPosition($index);
1558  }
1559 
1560  return $this->getOrderingElementList()->getElements();
1561  }
1562 
1566  protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1567  {
1568  parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1569  $this->duplicateImages($dupQuestionId, $dupParentObjId, $origQuestionId, $origParentObjId);
1570  }
1571 
1572  // fau: testNav - new function getTestQuestionConfig()
1577  // hey: refactored identifiers
1579  // hey.
1580  {
1581  // hey: refactored identifiers
1582  return parent::buildTestPresentationConfig()
1583  // hey.
1584  ->setIsUnchangedAnswerPossible(true)
1585  ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
1586  }
1587  // fau.
1588 
1589  protected function ensureImagePathExists()
1590  {
1591  if (!file_exists($this->getImagePath())) {
1593  }
1594  }
1595 
1599  public function fetchSolutionSubmit($formSubmissionDataStructure)
1600  {
1601  $solutionSubmit = array();
1602 
1603  if (isset($formSubmissionDataStructure['orderresult'])) {
1604  $orderresult = $formSubmissionDataStructure['orderresult'];
1605 
1606  if (strlen($orderresult)) {
1607  $orderarray = explode(":", $orderresult);
1608  $ordervalue = 1;
1609  foreach ($orderarray as $index) {
1610  $idmatch = null;
1611  if (preg_match("/id_(\\d+)/", $index, $idmatch)) {
1612  $randomid = $idmatch[1];
1613  foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1614  if ($answer->getRandomIdentifier() == $randomid) {
1615  $solutionSubmit[$answeridx] = $ordervalue;
1616  $ordervalue++;
1617  }
1618  }
1619  }
1620  }
1621  }
1622  } elseif ($this->getOrderingType() == OQ_NESTED_TERMS || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1623  $index = 0;
1624  foreach ($formSubmissionDataStructure['content'] as $randomId => $content) {
1625  $indentation = $formSubmissionDataStructure['indentation'];
1626 
1627  $value1 = $index++;
1628  $value2 = implode(':', array($randomId, $indentation));
1629 
1630  $solutionSubmit[$value1] = $value2;
1631  }
1632  } else {
1633  foreach ($formSubmissionDataStructure as $key => $value) {
1634  $matches = null;
1635  if (preg_match("/^order_(\d+)/", $key, $matches)) {
1636  if (!(preg_match("/initial_value_\d+/", $value))) {
1637  if (strlen($value)) {
1638  foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1639  if ($answer->getRandomIdentifier() == $matches[1]) {
1640  $solutionSubmit[$answeridx] = $value;
1641  }
1642  }
1643  }
1644  }
1645  }
1646  }
1647  }
1648 
1649  return $solutionSubmit;
1650  }
1651 
1656  {
1657  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingFormValuesObjectsConverter.php';
1658  $converter = new ilAssOrderingFormValuesObjectsConverter();
1659  $converter->setPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR);
1660 
1661  return $converter;
1662  }
1663 
1668  {
1669  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1671 
1672  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1673  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1674  $formDataConverter->setImageFsPath($this->getImagePath());
1675 
1676  if ($this->getThumbSize() && $this->getThumbPrefix()) {
1677  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1678  }
1679  return $formDataConverter;
1680  }
1681 
1686  {
1687  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1689  return $formDataConverter;
1690  }
1691 
1696  {
1697  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1699 
1700  if ($this->getOrderingType() == OQ_NESTED_PICTURES) {
1701  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1702  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1703 
1704  if ($this->getThumbSize() && $this->getThumbPrefix()) {
1705  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1706  }
1707  }
1708 
1709  return $formDataConverter;
1710  }
1711 }
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
$path
Definition: aliased.php:25
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
getSolutionOrderingElementListForTestOutput(ilAssNestedOrderingElementsInputGUI $inputGUI, $lastPost, $activeId, $pass)
Class iQuestionCondition.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
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 ...
global $DIC
Definition: saml.php:7
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)
$index
Definition: metadata.php:60
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)
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.
if(isset($_POST['submit'])) $form
$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.
deleteAnswer($randomIdentifier)
Deletes an answer with a given index.
setTitle($a_title)
Set Title.
$text
Definition: errorreport.php:18
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
$row
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)
const OQ_NESTED_PICTURES
global $ilDB
setOriginalId($original_id)
Class for ordering questions.
$i
Definition: disco.tpl.php:19
updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
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
$key
Definition: croninfo.php:18
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.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
$data
Definition: bench.php:6
getAnswerCount()
Returns the number of answers.