ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  var $thumb_geometry = 100;
54 
61 
64 
77  public function __construct(
78  $title = "",
79  $comment = "",
80  $author = "",
81  $owner = -1,
82  $question = "",
83  $ordering_type = OQ_TERMS
84  )
85  {
86  parent::__construct($title, $comment, $author, $owner, $question);
87  $this->orderingElementList = new ilAssOrderingElementList();
88  $this->ordering_type = $ordering_type;
89  }
90 
96  public function isComplete()
97  {
98  if( !$this->getAuthor() )
99  {
100  return false;
101  }
102 
103  if( !$this->getTitle() )
104  {
105  return false;
106  }
107 
108  if( !$this->getQuestion() )
109  {
110  return false;
111  }
112 
113  if( !$this->getMaximumPoints() )
114  {
115  return false;
116  }
117 
118  if( !$this->getOrderingElementList()->countElements() )
119  {
120  return false;
121  }
122 
123  return true;
124  }
125 
133  public function saveToDb($original_id = "")
134  {
135  global $ilDB;
136 
140  parent::saveToDb($original_id);
141  }
142 
150  function loadFromDb($question_id)
151  {
152  global $ilDB;
153 
154  $result = $ilDB->queryF("SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
155  array("integer"),
156  array($question_id)
157  );
158  if ($result->numRows() == 1)
159  {
160  $data = $ilDB->fetchAssoc($result);
161  $this->setId($question_id);
162  $this->setObjId($data["obj_fi"]);
163  $this->setTitle($data["title"]);
164  $this->setComment($data["description"]);
165  $this->setOriginalId($data["original_id"]);
166  $this->setAuthor($data["author"]);
167  $this->setNrOfTries($data['nr_of_tries']);
168  $this->setPoints($data["points"]);
169  $this->setOwner($data["owner"]);
170  include_once("./Services/RTE/classes/class.ilRTE.php");
171  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
172  $this->ordering_type = strlen($data["ordering_type"]) ? $data["ordering_type"] : OQ_TERMS;
173  $this->thumb_geometry = $data["thumb_geometry"];
174  $this->element_height = $data["element_height"];
175  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
176 
177  try
178  {
179  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
180  }
182  {
183  }
184  }
185 
186  $this->orderingElementList->setQuestionId($this->getId());
187  $this->orderingElementList->loadFromDb();
188 
189  parent::loadFromDb($question_id);
190  }
191 
197  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
198  {
199  if ($this->id <= 0)
200  {
201  // The question has not been saved. It cannot be duplicated
202  return;
203  }
204  // duplicate the question in database
205  $this_id = $this->getId();
206  $thisObjId = $this->getObjId();
207 
208  $clone = $this;
209  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
211  $clone->id = -1;
212 
213  if( (int)$testObjId > 0 )
214  {
215  $clone->setObjId($testObjId);
216  }
217 
218  if ($title)
219  {
220  $clone->setTitle($title);
221  }
222  if ($author)
223  {
224  $clone->setAuthor($author);
225  }
226  if ($owner)
227  {
228  $clone->setOwner($owner);
229  }
230  if ($for_test)
231  {
232  $clone->saveToDb($original_id);
233  }
234  else
235  {
236  $clone->saveToDb();
237  }
238 
239  $clone->duplicateOrderlingElementList();
240 
241  // copy question page content
242  $clone->copyPageOfQuestion($this_id);
243  // copy XHTML media objects
244  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
245  // duplicate the image
246  $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
247 
248  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
249 
250  return $clone->id;
251  }
252 
253  protected function duplicateOrderlingElementList()
254  {
255  $this->getOrderingElementList()->setQuestionId($this->getId());
256  $this->getOrderingElementList()->distributeNewRandomIdentifiers();
257  $this->getOrderingElementList()->saveToDb();
258  }
259 
265  function copyObject($target_questionpool_id, $title = "")
266  {
267  if ($this->id <= 0)
268  {
269  // The question has not been saved. It cannot be duplicated
270  return;
271  }
272  // duplicate the question in database
273  $clone = $this;
274  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
276  $clone->id = -1;
277  $source_questionpool_id = $this->getObjId();
278  $clone->setObjId($target_questionpool_id);
279  if ($title)
280  {
281  $clone->setTitle($title);
282  }
283 
284  $clone->saveToDb();
285 
286  // copy question page content
287  $clone->copyPageOfQuestion($original_id);
288  // copy XHTML media objects
289  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
290  // duplicate the image
291  $clone->duplicateImages($original_id, $source_questionpool_id, $clone->getId(), $target_questionpool_id);
292 
293  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
294 
295  return $clone->id;
296  }
297 
298  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
299  {
300  if ($this->id <= 0)
301  {
302  // The question has not been saved. It cannot be duplicated
303  return;
304  }
305 
306  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
307 
308  $sourceQuestionId = $this->id;
309  $sourceParentId = $this->getObjId();
310 
311  // duplicate the question in database
312  $clone = $this;
313  $clone->id = -1;
314 
315  $clone->setObjId($targetParentId);
316 
317  if ($targetQuestionTitle)
318  {
319  $clone->setTitle($targetQuestionTitle);
320  }
321 
322  $clone->saveToDb();
323  // copy question page content
324  $clone->copyPageOfQuestion($sourceQuestionId);
325  // copy XHTML media objects
326  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
327  // duplicate the image
328  $clone->duplicateImages($sourceQuestionId, $sourceParentId, $clone->getId(), $clone->getObjId());
329 
330  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
331 
332  return $clone->id;
333  }
334 
335  function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
336  {
337  global $ilLog;
338  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES)
339  {
340  $imagepath_original = $this->getImagePath($src_question_id, $src_object_id);
341  $imagepath = $this->getImagePath($dest_question_id, $dest_object_id);
342 
343  if (!file_exists($imagepath)) {
344  ilUtil::makeDirParents($imagepath);
345  }
346  foreach($this->getOrderingElementList() as $element)
347  {
348  $filename = $element->getContent();
349  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
350  {
351  $ilLog->write("image could not be duplicated!!!!");
352  }
353  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
354  {
355  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
356  {
357  $ilLog->write("image thumbnail could not be duplicated!!!!");
358  }
359  }
360  }
361  }
362  }
363 
369  function copyImages($question_id, $source_questionpool)
370  {
371  global $ilLog;
372  if ($this->getOrderingType() == OQ_PICTURES)
373  {
374  $imagepath = $this->getImagePath();
375  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
376  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
377  if (!file_exists($imagepath)) {
378  ilUtil::makeDirParents($imagepath);
379  }
380  foreach($this->getOrderingElementList() as $element)
381  {
382  $filename = $element->getContent();
383  if (!@copy($imagepath_original . $filename, $imagepath . $filename))
384  {
385  $ilLog->write("Ordering Question image could not be copied: ${imagepath_original}${filename}");
386  }
387  if (@file_exists($imagepath_original. $this->getThumbPrefix(). $filename))
388  {
389  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
390  {
391  $ilLog->write("Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
392  }
393  }
394  }
395  }
396  }
397 
405  function setOrderingType($ordering_type = OQ_TERMS)
406  {
407  $this->ordering_type = $ordering_type;
408  }
409 
417  function getOrderingType()
418  {
419  return $this->ordering_type;
420  }
421 
422  public function isOrderingTypeNested()
423  {
424  return in_array($this->getOrderingType(), array(OQ_NESTED_TERMS, OQ_NESTED_PICTURES));
425  }
426 
427  public function isImageOrderingType()
428  {
429  return in_array($this->getOrderingType(), array(OQ_PICTURES, OQ_NESTED_PICTURES));
430  }
431 
433  {
434  return $this->getOrderingType() == OQ_PICTURES;
435  }
436 
443  public function getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex)
444  {
445  if( $forceCorrectSolution || !$activeId || $passIndex === null )
446  {
447  return $this->getOrderingElementList();
448  }
449 
450  $solutionValues = $this->getSolutionValues($activeId, $passIndex);
451 
452  if( !count($solutionValues) )
453  {
454  return $this->getShuffledOrderingElementList();
455  }
456 
457  return $this->getSolutionOrderingElementList( $this->fetchIndexedValuesFromValuePairs($solutionValues) );
458  }
459 
470  {
471  if( $inputGUI->isPostSubmit($lastPost) )
472  {
473  return $this->fetchSolutionListFromFormSubmissionData($lastPost);
474  }
475 
476  // hey: prevPassSolutions - pass will be always available from now on
477  #if( $pass === null && !ilObjTest::_getUsePreviousAnswers($activeId, true) )
478  #// condition looks strange? yes - keep it null when previous solutions not enabled (!)
479  #{
480  # $pass = ilObjTest::_getPass($activeId);
481  #}
482  // hey.
483 
484  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs(
485  // hey: prevPassSolutions - obsolete due to central check
486  $this->getTestOutputSolutions($activeId, $pass)
487  // hey.
488  );
489 
490  if( count($indexedSolutionValues) )
491  {
492  return $this->getSolutionOrderingElementList($indexedSolutionValues);
493  }
494 
495  return $this->getShuffledOrderingElementList();
496  }
497 
504  {
505  $value2 = explode(':', $value2);
506 
507  $randomIdentifier = $value2[0];
508  $selectedPosition = $value1;
509  $selectedIndentation = $value2[1];
510 
511  $element = $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)->getClone();
512 
513  $element->setPosition($selectedPosition);
514  $element->setIndentation($selectedIndentation);
515 
516  return $element;
517  }
518 
525  {
526  $solutionIdentifier = $value1;
527  $selectedPosition = ($value2 - 1);
528  $selectedIndentation = 0;
529 
530  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($solutionIdentifier)->getClone();
531 
532  $element->setPosition($selectedPosition);
533  $element->setIndentation($selectedIndentation);
534 
535  return $element;
536  }
537 
543  public function getSolutionOrderingElementList($indexedSolutionValues)
544  {
545  $solutionOrderingList = new ilAssOrderingElementList();
546  $solutionOrderingList->setQuestionId($this->getId());
547 
548  foreach($indexedSolutionValues as $value1 => $value2)
549  {
550  if( $this->isOrderingTypeNested() )
551  {
552  $element = $this->getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2);
553  }
554  else
555  {
556  $element = $this->getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2);
557  }
558 
559  $solutionOrderingList->addElement($element);
560  }
561 
562  if( !$this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($solutionOrderingList) )
563  {
564  throw new ilTestQuestionPoolException('inconsistent solution values given');
565  }
566 
567  return $solutionOrderingList;
568  }
569 
576  {
577  $shuffledRandomIdentifierIndex = $this->getShuffler()->shuffle(
578  $this->getOrderingElementList()->getRandomIdentifierIndex()
579  );
580 
581  $shuffledElementList = $this->getOrderingElementList()->getClone();
582  $shuffledElementList->reorderByRandomIdentifiers($shuffledRandomIdentifierIndex);
583  $shuffledElementList->resetElementsIndentations();
584 
585  return $shuffledElementList;
586  }
587 
591  public function getOrderingElementList()
592  {
594  }
595 
600  {
601  $this->orderingElementList = $orderingElementList;
602  }
603 
609  public function moveAnswerUp($position)
610  {
611  if( !$this->getOrderingElementList()->elementExistByPosition($position) )
612  {
613  return false;
614  }
615 
616  if( $this->getOrderingElementList()->isFirstElementPosition($position) )
617  {
618  return false;
619  }
620 
621  $this->getOrderingElementList()->moveElementByPositions($position, $position - 1);
622  }
623 
629  public function moveAnswerDown($position)
630  {
631  if( !$this->getOrderingElementList()->elementExistByPosition($position) )
632  {
633  return false;
634  }
635 
636  if( $this->getOrderingElementList()->isLastElementPosition($position) )
637  {
638  return false;
639  }
640 
641  $this->getOrderingElementList()->moveElementByPositions($position, $position + 1);
642 
643  return true;
644  }
645 
652  public function getAnswer($index = 0)
653  {
654  if( !$this->getOrderingElementList()->elementExistByPosition($index) )
655  {
656  return null;
657  }
658 
659  return $this->getOrderingElementList()->getElementByPosition($index);
660  }
661 
670  function deleteAnswer($randomIdentifier)
671  {
672  $this->getOrderingElementList()->removeElement(
673  $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)
674  );
675  $this->getOrderingElementList()->saveToDb();
676  }
677 
685  function getAnswerCount()
686  {
687  return $this->getOrderingElementList()->countElements();
688  }
689 
700  public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
701  {
702  if( $returndetails )
703  {
704  throw new ilTestException('return details not implemented for '.__METHOD__);
705  }
706 
707  if (is_null($pass))
708  {
709  $pass = $this->getSolutionMaxPass($active_id);
710  }
711 
712  $solutionValuePairs = $this->getSolutionValues($active_id, $pass, $authorizedSolution);
713 
714  if( !count($solutionValuePairs) )
715  {
716  return 0;
717  }
718 
719  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs($solutionValuePairs);
720  $solutionOrderingElementList = $this->getSolutionOrderingElementList($indexedSolutionValues);
721 
722  return $this->calculateReachedPointsForSolution($solutionOrderingElementList);
723  }
724 
726  {
727  if( !$previewSession->hasParticipantSolution() )
728  {
729  return 0;
730  }
731 
732  $solutionOrderingElementList = unserialize(
733  $previewSession->getParticipantsSolution()
734  );
735 
736  $reachedPoints = $this->calculateReachedPointsForSolution($solutionOrderingElementList);
737  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
738 
739  return $this->ensureNonNegativePoints($reachedPoints);
740  }
741 
748  public function getMaximumPoints()
749  {
750  return $this->getPoints();
751  }
752 
753  /*
754  * Returns the encrypted save filename of a matching picture
755  * Images are saved with an encrypted filename to prevent users from
756  * cheating by guessing the solution from the image filename
757  *
758  * @param string $filename Original filename
759  * @return string Encrypted filename
760  */
762  {
763  $extension = "";
764  if (preg_match("/.*\\.(\\w+)$/", $filename, $matches))
765  {
766  $extension = $matches[1];
767  }
768  return md5($filename) . "." . $extension;
769  }
770 
771  protected function cleanImagefiles()
772  {
773  if ($this->getOrderingType() == OQ_PICTURES)
774  {
775  if (@file_exists($this->getImagePath()))
776  {
778  foreach ($contents as $f)
779  {
780  if (strcmp($f['type'], 'file') == 0)
781  {
782  $found = false;
783  foreach($this->getOrderingElementList() as $orderElement)
784  {
785  if (strcmp($f['entry'], $orderElement->getContent()) == 0) $found = true;
786  if (strcmp($f['entry'], $this->getThumbPrefix() . $orderElement->getContent()) == 0) $found = true;
787  }
788  if (!$found)
789  {
790  if (@file_exists($this->getImagePath() . $f['entry'])) @unlink($this->getImagePath() . $f['entry']);
791  }
792  }
793  }
794  }
795  }
796  else
797  {
798  if (@file_exists($this->getImagePath()))
799  {
800  ilUtil::delDir($this->getImagePath());
801  }
802  }
803  }
804 
805  /*
806  * Deletes an imagefile from the system if the file is deleted manually
807  *
808  * @param string $filename Image file filename
809  * @return boolean Success
810  */
811  public function dropImageFile($imageFilename)
812  {
813  if( !strlen($imageFilename) )
814  {
815  return false;
816  }
817 
818  $result = @unlink($this->getImagePath().$imageFilename);
819  $result = $result & @unlink($this->getImagePath().$this->getThumbPrefix() . $imageFilename);
820 
821  return $result;
822  }
823 
824  public function isImageFileStored($imageFilename)
825  {
826  if( !strlen($imageFilename) )
827  {
828  return false;
829  }
830 
831  if( !file_exists($this->getImagePath().$imageFilename) )
832  {
833  return false;
834  }
835 
836  return is_file($this->getImagePath().$imageFilename);
837  }
838 
839  public function isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement)
840  {
841  if( !$this->hasOrderingTypeUploadSupport() )
842  {
843  return false;
844  }
845 
846  if( !$newElement->getContent() )
847  {
848  return false;
849  }
850 
851  return $newElement->getContent() != $oldElement->getContent();
852  }
853 
862  function storeImageFile($uploadFile, $targetFile)
863  {
864  if( !strlen($uploadFile) )
865  {
866  return false;
867  }
868 
869  $this->ensureImagePathExists();
870 
871  // store file with hashed name
872 
873  if( !ilUtil::moveUploadedFile($uploadFile, $targetFile, $this->getImagePath().$targetFile) )
874  {
875  return false;
876  }
877 
878  return true;
879  }
880 
881  public function handleThumbnailCreation(ilAssOrderingElementList $elementList)
882  {
883  foreach($elementList as $element)
884  {
885  $this->createImageThumbnail($element);
886  }
887  }
888 
889  public function createImageThumbnail(ilAssOrderingElement $element)
890  {
891  if( $this->getThumbGeometry() )
892  {
893  $imageFile = $this->getImagePath() . $element->getContent();
894  $thumbFile = $this->getImagePath() . $this->getThumbPrefix().$element->getContent();
895 
896  ilUtil::convertImage( $imageFile, $thumbFile, "JPEG", $this->getThumbGeometry() );
897  }
898  }
899 
907  public function validateSolutionSubmit()
908  {
909  $submittedSolutionList = $this->getSolutionListFromPostSubmit();
910  return $this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($submittedSolutionList);
911  }
912 
921  public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
922  {
923  $entered_values = 0;
924 
925  if (is_null($pass))
926  {
927  include_once "./Modules/Test/classes/class.ilObjTest.php";
928  $pass = ilObjTest::_getPass($active_id);
929  }
930 
931  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(
932  function() use (&$entered_values, $active_id, $pass, $authorized)
933  {
934  $this->removeCurrentSolution($active_id, $pass, $authorized);
935 
936  foreach( $this->getSolutionListFromPostSubmit() as $orderingElement)
937  {
938  $value1 = $orderingElement->getStorageValue1($this->getOrderingType());
939  $value2 = $orderingElement->getStorageValue2($this->getOrderingType());
940 
941  $this->saveCurrentSolution($active_id, $pass, $value1, trim($value2), $authorized);
942 
943  $entered_values++;
944  }
945  }
946  );
947 
948  if ($entered_values)
949  {
950  $this->log($active_id, 'log_user_entered_values');
951  }
952  else
953  {
954  $this->log($active_id, 'log_user_not_entered_values');
955  }
956 
957  return true;
958  }
959 
960  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
961  {
962  if( $this->validateSolutionSubmit() )
963  {
964  $previewSession->setParticipantsSolution( serialize($this->getSolutionListFromPostSubmit()) );
965  }
966  }
967 
968  public function saveAdditionalQuestionDataToDb()
969  {
971  global $ilDB;
972 
973  // save additional data
974  $ilDB->manipulateF( "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
975  array( "integer" ),
976  array( $this->getId() )
977  );
978 
979  $ilDB->manipulateF( "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, ordering_type, thumb_geometry, element_height)
980  VALUES (%s, %s, %s, %s)",
981  array( "integer", "text", "integer", "integer" ),
982  array(
983  $this->getId(),
984  $this->ordering_type,
985  $this->getThumbGeometry(),
986  ($this->getElementHeight() > 20) ? $this->getElementHeight() : NULL
987  )
988  );
989  }
990 
991  public function saveAnswerSpecificDataToDb()
992  {
993  $this->getOrderingElementList()->setQuestionId($this->getId());
994  $this->getOrderingElementList()->saveToDb();
995 
996  if( $this->hasOrderingTypeUploadSupport() )
997  {
998  $this->rebuildThumbnails();
999  $this->cleanImagefiles();
1000  }
1001  }
1002 
1006  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
1007  {
1008  // nothing to rework!
1009  }
1010 
1017  function getQuestionType()
1018  {
1019  return "assOrderingQuestion";
1020  }
1021 
1029  {
1030  return "qpl_qst_ordering";
1031  }
1032 
1040  {
1041  return "qpl_a_ordering";
1042  }
1043 
1049  {
1050  $text = parent::getRTETextWithMediaObjects();
1051 
1052  foreach ( $this->getOrderingElementList() as $orderingElement)
1053  {
1054  $text .= $orderingElement->getContent();
1055  }
1056 
1057  return $text;
1058  }
1059 
1064  function getOrderElements()
1065  {
1066  return $this->getOrderingElementList()->getRandomIdentifierIndexedElements();
1067  }
1068 
1075  public function supportsJavascriptOutput()
1076  {
1077  return TRUE;
1078  }
1079 
1080  public function supportsNonJsOutput()
1081  {
1082  return false;
1083  }
1084 
1088  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1089  {
1090  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1091 
1092  $solutions = $this->getSolutionValues($active_id, $pass);
1093  $sol = array();
1094  foreach ($solutions as $solution)
1095  {
1096  $sol[$solution["value1"]] = $solution["value2"];
1097  }
1098  asort($sol);
1099  $sol = array_keys($sol);
1100 
1101  $i = 1;
1102  foreach ($sol as $idx)
1103  {
1104  foreach ($solutions as $solution)
1105  {
1106  if ($solution["value1"] == $idx) $worksheet->setCell($startrow + $i, 0, $solution["value2"]);
1107  }
1108  $element = $this->getOrderingElementList()->getElementByPosition($idx);
1109  $worksheet->setCell($startrow + $i, 1, $element->getContent());
1110  $i++;
1111  }
1112 
1113  return $startrow + $i + 1;
1114  }
1115 
1116  /*
1117  * Get the thumbnail geometry
1118  *
1119  * @return integer Geometry
1120  */
1121  public function getThumbGeometry()
1122  {
1123  return $this->thumb_geometry;
1124  }
1125 
1126  public function getThumbSize()
1127  {
1128  return $this->getThumbGeometry();
1129  }
1130 
1131  /*
1132  * Set the thumbnail geometry
1133  *
1134  * @param integer $a_geometry Geometry
1135  */
1136  public function setThumbGeometry($a_geometry)
1137  {
1138  $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1139  }
1140 
1141  /*
1142  * Get the minimum element height
1143  *
1144  * @return integer Height
1145  */
1146  public function getElementHeight()
1147  {
1148  return $this->element_height;
1149  }
1150 
1151  /*
1152  * Set the minimum element height
1153  *
1154  * @param integer $a_height Height
1155  */
1156  public function setElementHeight($a_height)
1157  {
1158  $this->element_height = ($a_height < 20) ? "" : $a_height;
1159  }
1160 
1161  /*
1162  * Rebuild the thumbnail images with a new thumbnail size
1163  */
1164  public function rebuildThumbnails()
1165  {
1166  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES)
1167  {
1168  foreach ( $this->getOrderElements() as $orderingElement)
1169  {
1170  $this->generateThumbForFile($this->getImagePath(), $orderingElement->getContent());
1171  }
1172  }
1173  }
1174 
1175  public function getThumbPrefix()
1176  {
1177  return "thumb.";
1178  }
1179 
1180  protected function generateThumbForFile($path, $file)
1181  {
1182  $filename = $path . $file;
1183  if (@file_exists($filename))
1184  {
1185  $thumbpath = $path . $this->getThumbPrefix() . $file;
1186  $path_info = @pathinfo($filename);
1187  $ext = "";
1188  switch (strtoupper($path_info['extension']))
1189  {
1190  case 'PNG':
1191  $ext = 'PNG';
1192  break;
1193  case 'GIF':
1194  $ext = 'GIF';
1195  break;
1196  default:
1197  $ext = 'JPEG';
1198  break;
1199  }
1200  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1201  }
1202  }
1203 
1207  public function toJSON()
1208  {
1209  include_once("./Services/RTE/classes/class.ilRTE.php");
1210  $result = array();
1211  $result['id'] = (int) $this->getId();
1212  $result['type'] = (string) $this->getQuestionType();
1213  $result['title'] = (string) $this->getTitle();
1214  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1215  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1216  $result['shuffle'] = (bool) true;
1217  $result['points'] = $this->getPoints();
1218  $result['feedback'] = array(
1219  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1220  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1221  );
1222  if ($this->getOrderingType() == OQ_PICTURES)
1223  {
1224  $result['path'] = $this->getImagePathWeb();
1225  }
1226 
1227  $counter = 1;
1228  $answers = array();
1229  foreach ( $this->getOrderingElementList() as $orderingElement)
1230  {
1231  $answers[$counter] = $orderingElement->getContent();
1232  $counter++;
1233  }
1234  $answers = $this->getShuffler()->shuffle($answers);
1235  $arr = array();
1236  foreach ($answers as $order => $answer)
1237  {
1238  array_push($arr, array(
1239  "answertext" => (string) $answer,
1240  "order" => (int) $order
1241  ));
1242  }
1243  $result['answers'] = $arr;
1244 
1245  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1246  $result['mobs'] = $mobs;
1247 
1248  return json_encode($result);
1249  }
1250 
1256  {
1257  switch( $this->getOrderingType() )
1258  {
1259  case OQ_TERMS:
1260 
1261  return $this->buildOrderingTextsInputGui();
1262 
1263  case OQ_PICTURES:
1264 
1265  return $this->buildOrderingImagesInputGui();
1266 
1267  case OQ_NESTED_TERMS:
1268  case OQ_NESTED_PICTURES:
1269 
1270  return $this->buildNestedOrderingElementInputGui();
1271 
1272  default:
1273  throw new ilTestQuestionPoolException('unknown ordering mode');
1274  }
1275  }
1276 
1281  {
1282  switch( true )
1283  {
1284  case $formField instanceof ilAssNestedOrderingElementsInputGUI:
1285 
1286  $formField->setInteractionEnabled(true);
1287  $formField->setNestingEnabled($this->isOrderingTypeNested());
1288  break;
1289 
1290  case $formField instanceof ilAssOrderingTextsInputGUI:
1291  case $formField instanceof ilAssOrderingImagesInputGUI:
1292  default:
1293 
1294  $formField->setEditElementOccuranceEnabled(true);
1295  $formField->setEditElementOrderEnabled(true);
1296  }
1297 
1298  $formField->setRequired(true);
1299  }
1300 
1305  {
1306  $formField->setInfo($this->lng->txt('ordering_answer_sequence_info'));
1307  $formField->setTitle($this->lng->txt('answers'));
1308  }
1309 
1313  public function buildOrderingTextsInputGui()
1314  {
1315  $formDataConverter = $this->buildOrderingTextsFormDataConverter();
1316 
1317  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingTextsInputGUI.php';
1318 
1319  $orderingElementInput = new ilAssOrderingTextsInputGUI(
1320  $formDataConverter, self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1321  );
1322 
1323  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1324 
1325  return $orderingElementInput;
1326  }
1327 
1332  {
1333  $formDataConverter = $this->buildOrderingImagesFormDataConverter();
1334 
1335  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingImagesInputGUI.php';
1336 
1337  $orderingElementInput = new ilAssOrderingImagesInputGUI(
1338  $formDataConverter, self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1339  );
1340 
1341  $orderingElementInput->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1342  $orderingElementInput->setImageUploadCommand(self::ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG);
1343 
1344  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1345 
1346  return $orderingElementInput;
1347  }
1348 
1353  {
1354  $formDataConverter = $this->buildNestedOrderingFormDataConverter();
1355 
1356  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php';
1357 
1358  $orderingElementInput = new ilAssNestedOrderingElementsInputGUI(
1359  $formDataConverter, self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1360  );
1361 
1362  $orderingElementInput->setUniquePrefix($this->getId());
1363  $orderingElementInput->setOrderingType($this->getOrderingType());
1364  $orderingElementInput->setElementImagePath($this->getImagePathWeb());
1365  $orderingElementInput->setThumbPrefix($this->getThumbPrefix());
1366 
1367  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1368 
1369  return $orderingElementInput;
1370  }
1371 
1377  {
1378  return $form->getItemByPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR)->getElementList($this->getId());
1379  }
1380 
1386  public function fetchSolutionListFromFormSubmissionData($userSolutionPost)
1387  {
1388  $orderingGUI = $this->buildNestedOrderingElementInputGui();
1390  $orderingGUI->setValueByArray($userSolutionPost);
1391 
1392  if( !$orderingGUI->checkInput() )
1393  {
1394  require_once 'Modules/Test/exceptions/class.ilTestException.php';
1395  throw new ilTestException('error on validating user solution post');
1396  }
1397 
1398  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssOrderingElementList.php';
1399  $solutionOrderingElementList = ilAssOrderingElementList::buildInstance($this->getId());
1400 
1401  $storedElementList = $this->getOrderingElementList();
1402 
1403  foreach($orderingGUI->getElementList($this->getId()) as $submittedElement)
1404  {
1405  $solutionElement = $storedElementList->getElementByRandomIdentifier(
1406  $submittedElement->getRandomIdentifier()
1407  )->getClone();
1408 
1409  $solutionElement->setPosition($submittedElement->getPosition());
1410 
1411  if( $this->isOrderingTypeNested() )
1412  {
1413  $solutionElement->setIndentation($submittedElement->getIndentation());
1414  }
1415 
1416  $solutionOrderingElementList->addElement($solutionElement);
1417  }
1418 
1419  return $solutionOrderingElementList;
1420  }
1421 
1426 
1431  {
1432  if( $this->postSolutionOrderingElementList === null )
1433  {
1435  $this->postSolutionOrderingElementList = $list;
1436  }
1437 
1439  }
1440 
1444  public function getSolutionPostSubmit()
1445  {
1446  return $this->fetchSolutionSubmit($_POST);
1447  }
1448 
1454  protected function calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList)
1455  {
1456  $reachedPoints = $this->getPoints();
1457 
1458  foreach($this->getOrderingElementList() as $correctElement)
1459  {
1460  $userElement = $solutionOrderingElementList->getElementByPosition( $correctElement->getPosition() );
1461 
1462  if( !$correctElement->isSameElement($userElement) )
1463  {
1464  $reachedPoints = 0;
1465  break;
1466  }
1467  }
1468 
1469  return $reachedPoints;
1470  }
1471 
1472  /***
1473  * @param object $child
1474  * @param integer $ordering_depth
1475  * @param bool $with_random_id
1476  */
1477  public function getLeveledOrdering()
1478  {
1479  return $this->leveled_ordering;
1480  }
1481 
1482  public function getOldLeveledOrdering()
1483  {
1484  global $ilDB;
1485 
1486  $res = $ilDB->queryF('SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY position ASC',
1487  array('integer'), array($this->getId()));
1488  while($row = $ilDB->fetchAssoc($res))
1489  {
1490  $this->old_ordering_depth[] = $row['depth'];
1491  }
1493  }
1494 
1495  /***
1496  * @param integer $a_random_id
1497  * @return integer
1498  */
1499  public function lookupSolutionOrderByRandomid($a_random_id)
1500  {
1501  global $ilDB;
1502 
1503  $res = $ilDB->queryF('SELECT solution_key FROM qpl_a_ordering WHERE random_id = %s',
1504  array('integer'), array($a_random_id));
1505  $row = $ilDB->fetchAssoc($res);
1506 
1507  return $row['solution_key'];
1508  }
1509 
1510  public function updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
1511  {
1512  global $ilDB;
1513 
1514  $ilDB->update('qpl_a_ordering',
1515  array('solution_key'=> array('integer', $a_index),
1516  'depth' => array('integer', $a_depth)),
1517  array('answertext' => array('text', $a_answer_text)));
1518 
1519 
1520  return true;
1521  }
1522 
1531  public function getOperators($expression)
1532  {
1533  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1535  }
1536 
1541  public function getExpressionTypes()
1542  {
1543  return array(
1548  );
1549  }
1550 
1559  public function getUserQuestionResult($active_id, $pass)
1560  {
1562  global $ilDB;
1563  $result = new ilUserQuestionResult($this, $active_id, $pass);
1564 
1565  $maxStep = $this->lookupMaxStep($active_id, $pass);
1566 
1567  if( $maxStep !== null )
1568  {
1569  $data = $ilDB->queryF(
1570  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY value1 ASC ",
1571  array("integer", "integer", "integer","integer"),
1572  array($active_id, $pass, $this->getId(), $maxStep)
1573  );
1574  }
1575  else
1576  {
1577  $data = $ilDB->queryF(
1578  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY value1 ASC ",
1579  array("integer", "integer", "integer"),
1580  array($active_id, $pass, $this->getId())
1581  );
1582  }
1583 
1584  $elements = array();
1585  while($row = $ilDB->fetchAssoc($data))
1586  {
1587 
1588  $newKey = explode(":", $row["value2"]);
1589 
1590  foreach( $this->getOrderingElementList() as $answer)
1591  {
1592  // Images nut supported
1593  if( !$this->isOrderingTypeNested() )
1594  {
1595  if($answer->getSolutionIdentifier() == $row["value1"])
1596  {
1597  $elements[$row["value2"]] = $answer->getSolutionIdentifier() + 1;
1598  break;
1599  }
1600  }
1601  else
1602  {
1603  if($answer->getRandomIdentifier() == $newKey[0])
1604  {
1605  $elements[$row["value1"]] = $answer->getSolutionIdentifier() + 1;
1606  break;
1607  }
1608  }
1609  }
1610  }
1611 
1612  ksort($elements);
1613 
1614  foreach(array_values($elements) as $element)
1615  {
1616  $result->addKeyValue($element, $element);
1617  }
1618 
1619  $points = $this->calculateReachedPoints($active_id, $pass);
1620  $max_points = $this->getMaximumPoints();
1621 
1622  $result->setReachedPercentage(($points/$max_points) * 100);
1623 
1624  return $result;
1625  }
1626 
1635  public function getAvailableAnswerOptions($index = null)
1636  {
1637  if($index !== null)
1638  {
1639  return $this->getOrderingElementList()->getElementByPosition($index);
1640  }
1641 
1642  return $this->getOrderingElementList()->getElements();
1643  }
1644 
1648  protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1649  {
1650  parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1651  $this->duplicateImages($dupQuestionId, $dupParentObjId, $origQuestionId, $origParentObjId);
1652  }
1653 
1654 // fau: testNav - new function getTestQuestionConfig()
1659  // hey: refactored identifiers
1661  // hey.
1662  {
1663  // hey: refactored identifiers
1664  return parent::buildTestPresentationConfig()
1665  // hey.
1666  ->setIsUnchangedAnswerPossible(true)
1667  ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
1668  }
1669  // fau.
1670 
1671  protected function ensureImagePathExists()
1672  {
1673  if( !file_exists($this->getImagePath()) )
1674  {
1676  }
1677  }
1678 
1682  public function fetchSolutionSubmit($formSubmissionDataStructure)
1683  {
1684  $solutionSubmit = array();
1685 
1686  if( isset($formSubmissionDataStructure['orderresult']) )
1687  {
1688  $orderresult = $formSubmissionDataStructure['orderresult'];
1689 
1690  if( strlen($orderresult) )
1691  {
1692  $orderarray = explode(":", $orderresult);
1693  $ordervalue = 1;
1694  foreach( $orderarray as $index )
1695  {
1696  $idmatch = null;
1697  if( preg_match("/id_(\\d+)/", $index, $idmatch) )
1698  {
1699  $randomid = $idmatch[1];
1700  foreach( $this->getOrderingElementList() as $answeridx => $answer )
1701  {
1702  if( $answer->getRandomIdentifier() == $randomid )
1703  {
1704  $solutionSubmit[$answeridx] = $ordervalue;
1705  $ordervalue++;
1706  }
1707  }
1708  }
1709  }
1710  }
1711  }
1712  else if( $this->getOrderingType() == OQ_NESTED_TERMS || $this->getOrderingType() == OQ_NESTED_PICTURES )
1713  {
1714  $index = 0;
1715  foreach( $formSubmissionDataStructure['content'] as $randomId => $content )
1716  {
1717  $indentation = $formSubmissionDataStructure['indentation'];
1718 
1719  $value1 = $index++;
1720  $value2 = implode(':', array($randomId, $indentation));
1721 
1722  $solutionSubmit[$value1] = $value2;
1723  }
1724  }
1725  else
1726  {
1727  foreach( $formSubmissionDataStructure as $key => $value )
1728  {
1729  $matches = null;
1730  if( preg_match("/^order_(\d+)/", $key, $matches) )
1731  {
1732  if( !( preg_match("/initial_value_\d+/", $value) ) )
1733  {
1734  if( strlen($value) )
1735  {
1736  foreach( $this->getOrderingElementList() as $answeridx => $answer )
1737  {
1738  if( $answer->getRandomIdentifier() == $matches[1] )
1739  {
1740  $solutionSubmit[$answeridx] = $value;
1741  }
1742  }
1743  }
1744  }
1745  }
1746  }
1747  }
1748 
1749  return $solutionSubmit;
1750  }
1751 
1756  {
1757  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingFormValuesObjectsConverter.php';
1758  $converter = new ilAssOrderingFormValuesObjectsConverter();
1759  $converter->setPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR);
1760 
1761  return $converter;
1762  }
1763 
1768  {
1769  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1771 
1772  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1773  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1774  $formDataConverter->setImageFsPath($this->getImagePath());
1775 
1776  if( $this->getThumbSize() && $this->getThumbPrefix() )
1777  {
1778  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1779  }
1780  return $formDataConverter;
1781  }
1782 
1787  {
1788  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1790  return $formDataConverter;
1791  }
1792 
1797  {
1798  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1800 
1801  if( $this->getOrderingType() == OQ_NESTED_PICTURES )
1802  {
1803  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1804  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1805 
1806  if( $this->getThumbSize() && $this->getThumbPrefix() )
1807  {
1808  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1809  }
1810  }
1811 
1812  return $formDataConverter;
1813  }
1814 }
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.
$worksheet
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 ...
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.
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)
Add rich text string
The name of the decorator.
getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex)
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)
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
setInfo($a_info)
Set Information Text.
$counter
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.
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)
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{}
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.
createImageThumbnail(ilAssOrderingElement $element)
storeImageFile($uploadFile, $targetFile)
Sets the image file and uploads the image to the object&#39;s image directory.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
setOrderingElementList($orderingElementList)
Create styles array
The data for the language used.
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.
static convertImage($a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
const OQ_NESTED_PICTURES
global $ilDB
setOriginalId($original_id)
Class for ordering questions.
$text
updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
getTitle()
Gets the title string of the assQuestion object.
buildTestPresentationConfig()
Get the test question configuration.
handleThumbnailCreation(ilAssOrderingElementList $elementList)
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
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.
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.