ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 
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 $ilDB;
130 
134  parent::saveToDb($original_id);
135  }
136 
144  public function loadFromDb($question_id)
145  {
146  global $ilDB;
147 
148  $result = $ilDB->queryF(
149  "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",
150  array("integer"),
151  array($question_id)
152  );
153  if ($result->numRows() == 1) {
154  $data = $ilDB->fetchAssoc($result);
155  $this->setId($question_id);
156  $this->setObjId($data["obj_fi"]);
157  $this->setTitle($data["title"]);
158  $this->setComment($data["description"]);
159  $this->setOriginalId($data["original_id"]);
160  $this->setAuthor($data["author"]);
161  $this->setNrOfTries($data['nr_of_tries']);
162  $this->setPoints($data["points"]);
163  $this->setOwner($data["owner"]);
164  include_once("./Services/RTE/classes/class.ilRTE.php");
165  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
166  $this->ordering_type = strlen($data["ordering_type"]) ? $data["ordering_type"] : OQ_TERMS;
167  $this->thumb_geometry = $data["thumb_geometry"];
168  $this->element_height = $data["element_height"];
169  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
170 
171  try {
172  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
173  } catch (ilTestQuestionPoolException $e) {
174  }
175  }
176 
177  $this->orderingElementList->setQuestionId($this->getId());
178  $this->orderingElementList->loadFromDb();
179 
180  parent::loadFromDb($question_id);
181  }
182 
188  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
189  {
190  if ($this->id <= 0) {
191  // The question has not been saved. It cannot be duplicated
192  return;
193  }
194  // duplicate the question in database
195  $this_id = $this->getId();
196  $thisObjId = $this->getObjId();
197 
198  $clone = $this;
199  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
201  $clone->id = -1;
202 
203  if ((int) $testObjId > 0) {
204  $clone->setObjId($testObjId);
205  }
206 
207  if ($title) {
208  $clone->setTitle($title);
209  }
210  if ($author) {
211  $clone->setAuthor($author);
212  }
213  if ($owner) {
214  $clone->setOwner($owner);
215  }
216  if ($for_test) {
217  $clone->saveToDb($original_id);
218  } else {
219  $clone->saveToDb();
220  }
221 
222  $clone->duplicateOrderlingElementList();
223 
224  // copy question page content
225  $clone->copyPageOfQuestion($this_id);
226  // copy XHTML media objects
227  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
228  // duplicate the image
229  $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
230 
231  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
232 
233  return $clone->id;
234  }
235 
236  protected function duplicateOrderlingElementList()
237  {
238  $this->getOrderingElementList()->setQuestionId($this->getId());
239  $this->getOrderingElementList()->distributeNewRandomIdentifiers();
240  $this->getOrderingElementList()->saveToDb();
241  }
242 
248  public function copyObject($target_questionpool_id, $title = "")
249  {
250  if ($this->id <= 0) {
251  // The question has not been saved. It cannot be duplicated
252  return;
253  }
254  // duplicate the question in database
255  $clone = $this;
256  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
258  $clone->id = -1;
259  $source_questionpool_id = $this->getObjId();
260  $clone->setObjId($target_questionpool_id);
261  if ($title) {
262  $clone->setTitle($title);
263  }
264 
265  $clone->saveToDb();
266 
267  // copy question page content
268  $clone->copyPageOfQuestion($original_id);
269  // copy XHTML media objects
270  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
271  // duplicate the image
272  $clone->duplicateImages($original_id, $source_questionpool_id, $clone->getId(), $target_questionpool_id);
273 
274  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
275 
276  return $clone->id;
277  }
278 
279  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
280  {
281  if ($this->id <= 0) {
282  // The question has not been saved. It cannot be duplicated
283  return;
284  }
285 
286  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
287 
288  $sourceQuestionId = $this->id;
289  $sourceParentId = $this->getObjId();
290 
291  // duplicate the question in database
292  $clone = $this;
293  $clone->id = -1;
294 
295  $clone->setObjId($targetParentId);
296 
297  if ($targetQuestionTitle) {
298  $clone->setTitle($targetQuestionTitle);
299  }
300 
301  $clone->saveToDb();
302  // copy question page content
303  $clone->copyPageOfQuestion($sourceQuestionId);
304  // copy XHTML media objects
305  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
306  // duplicate the image
307  $clone->duplicateImages($sourceQuestionId, $sourceParentId, $clone->getId(), $clone->getObjId());
308 
309  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
310 
311  return $clone->id;
312  }
313 
314  public function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
315  {
316  global $ilLog;
317  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES) {
318  $imagepath_original = $this->getImagePath($src_question_id, $src_object_id);
319  $imagepath = $this->getImagePath($dest_question_id, $dest_object_id);
320 
321  if (!file_exists($imagepath)) {
322  ilUtil::makeDirParents($imagepath);
323  }
324  foreach ($this->getOrderingElementList() as $element) {
325  $filename = $element->getContent();
326  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
327  $ilLog->write("image could not be duplicated!!!!");
328  }
329  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
330  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
331  $ilLog->write("image thumbnail could not be duplicated!!!!");
332  }
333  }
334  }
335  }
336  }
337 
343  public function copyImages($question_id, $source_questionpool)
344  {
345  global $ilLog;
346  if ($this->getOrderingType() == OQ_PICTURES) {
347  $imagepath = $this->getImagePath();
348  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
349  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
350  if (!file_exists($imagepath)) {
351  ilUtil::makeDirParents($imagepath);
352  }
353  foreach ($this->getOrderingElementList() as $element) {
354  $filename = $element->getContent();
355  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
356  $ilLog->write("Ordering Question image could not be copied: ${imagepath_original}${filename}");
357  }
358  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
359  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
360  $ilLog->write("Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
361  }
362  }
363  }
364  }
365  }
366 
375  {
376  $this->ordering_type = $ordering_type;
377  }
378 
386  public function getOrderingType()
387  {
388  return $this->ordering_type;
389  }
390 
391  public function isOrderingTypeNested()
392  {
393  return in_array($this->getOrderingType(), array(OQ_NESTED_TERMS, OQ_NESTED_PICTURES));
394  }
395 
396  public function isImageOrderingType()
397  {
398  return in_array($this->getOrderingType(), array(OQ_PICTURES, OQ_NESTED_PICTURES));
399  }
400 
402  {
403  return $this->getOrderingType() == OQ_PICTURES;
404  }
405 
412  public function getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex)
413  {
414  if ($forceCorrectSolution || !$activeId || $passIndex === null) {
415  return $this->getOrderingElementList();
416  }
417 
418  $solutionValues = $this->getSolutionValues($activeId, $passIndex);
419 
420  if (!count($solutionValues)) {
421  return $this->getShuffledOrderingElementList();
422  }
423 
424  return $this->getSolutionOrderingElementList($this->fetchIndexedValuesFromValuePairs($solutionValues));
425  }
426 
437  {
438  if ($inputGUI->isPostSubmit($lastPost)) {
439  return $this->fetchSolutionListFromFormSubmissionData($lastPost);
440  }
441 
442  // hey: prevPassSolutions - pass will be always available from now on
443  #if( $pass === null && !ilObjTest::_getUsePreviousAnswers($activeId, true) )
444  #// condition looks strange? yes - keep it null when previous solutions not enabled (!)
445  #{
446  # $pass = ilObjTest::_getPass($activeId);
447  #}
448  // hey.
449 
450  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs(
451  // hey: prevPassSolutions - obsolete due to central check
452  $this->getTestOutputSolutions($activeId, $pass)
453  // hey.
454  );
455 
456  if (count($indexedSolutionValues)) {
457  return $this->getSolutionOrderingElementList($indexedSolutionValues);
458  }
459 
460  return $this->getShuffledOrderingElementList();
461  }
462 
469  {
470  $value2 = explode(':', $value2);
471 
472  $randomIdentifier = $value2[0];
473  $selectedPosition = $value1;
474  $selectedIndentation = $value2[1];
475 
476  $element = $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)->getClone();
477 
478  $element->setPosition($selectedPosition);
479  $element->setIndentation($selectedIndentation);
480 
481  return $element;
482  }
483 
490  {
491  $solutionIdentifier = $value1;
492  $selectedPosition = ($value2 - 1);
493  $selectedIndentation = 0;
494 
495  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($solutionIdentifier)->getClone();
496 
497  $element->setPosition($selectedPosition);
498  $element->setIndentation($selectedIndentation);
499 
500  return $element;
501  }
502 
508  public function getSolutionOrderingElementList($indexedSolutionValues)
509  {
510  $solutionOrderingList = new ilAssOrderingElementList();
511  $solutionOrderingList->setQuestionId($this->getId());
512 
513  foreach ($indexedSolutionValues as $value1 => $value2) {
514  if ($this->isOrderingTypeNested()) {
515  $element = $this->getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2);
516  } else {
517  $element = $this->getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2);
518  }
519 
520  $solutionOrderingList->addElement($element);
521  }
522 
523  if (!$this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($solutionOrderingList)) {
524  throw new ilTestQuestionPoolException('inconsistent solution values given');
525  }
526 
527  return $solutionOrderingList;
528  }
529 
536  {
537  $shuffledRandomIdentifierIndex = $this->getShuffler()->shuffle(
538  $this->getOrderingElementList()->getRandomIdentifierIndex()
539  );
540 
541  $shuffledElementList = $this->getOrderingElementList()->getClone();
542  $shuffledElementList->reorderByRandomIdentifiers($shuffledRandomIdentifierIndex);
543  $shuffledElementList->resetElementsIndentations();
544 
545  return $shuffledElementList;
546  }
547 
551  public function getOrderingElementList()
552  {
554  }
555 
560  {
561  $this->orderingElementList = $orderingElementList;
562  }
563 
569  public function moveAnswerUp($position)
570  {
571  if (!$this->getOrderingElementList()->elementExistByPosition($position)) {
572  return false;
573  }
574 
575  if ($this->getOrderingElementList()->isFirstElementPosition($position)) {
576  return false;
577  }
578 
579  $this->getOrderingElementList()->moveElementByPositions($position, $position - 1);
580  }
581 
587  public function moveAnswerDown($position)
588  {
589  if (!$this->getOrderingElementList()->elementExistByPosition($position)) {
590  return false;
591  }
592 
593  if ($this->getOrderingElementList()->isLastElementPosition($position)) {
594  return false;
595  }
596 
597  $this->getOrderingElementList()->moveElementByPositions($position, $position + 1);
598 
599  return true;
600  }
601 
608  public function getAnswer($index = 0)
609  {
610  if (!$this->getOrderingElementList()->elementExistByPosition($index)) {
611  return null;
612  }
613 
614  return $this->getOrderingElementList()->getElementByPosition($index);
615  }
616 
625  public function deleteAnswer($randomIdentifier)
626  {
627  $this->getOrderingElementList()->removeElement(
628  $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)
629  );
630  $this->getOrderingElementList()->saveToDb();
631  }
632 
640  public function getAnswerCount()
641  {
642  return $this->getOrderingElementList()->countElements();
643  }
644 
655  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
656  {
657  if ($returndetails) {
658  throw new ilTestException('return details not implemented for ' . __METHOD__);
659  }
660 
661  if (is_null($pass)) {
662  $pass = $this->getSolutionMaxPass($active_id);
663  }
664 
665  $solutionValuePairs = $this->getSolutionValues($active_id, $pass, $authorizedSolution);
666 
667  if (!count($solutionValuePairs)) {
668  return 0;
669  }
670 
671  $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs($solutionValuePairs);
672  $solutionOrderingElementList = $this->getSolutionOrderingElementList($indexedSolutionValues);
673 
674  return $this->calculateReachedPointsForSolution($solutionOrderingElementList);
675  }
676 
678  {
679  if (!$previewSession->hasParticipantSolution()) {
680  return 0;
681  }
682 
683  $solutionOrderingElementList = unserialize(
684  $previewSession->getParticipantsSolution()
685  );
686 
687  $reachedPoints = $this->calculateReachedPointsForSolution($solutionOrderingElementList);
688  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
689 
690  return $this->ensureNonNegativePoints($reachedPoints);
691  }
692 
699  public function getMaximumPoints()
700  {
701  return $this->getPoints();
702  }
703 
704  /*
705  * Returns the encrypted save filename of a matching picture
706  * Images are saved with an encrypted filename to prevent users from
707  * cheating by guessing the solution from the image filename
708  *
709  * @param string $filename Original filename
710  * @return string Encrypted filename
711  */
713  {
714  $extension = "";
715  if (preg_match("/.*\\.(\\w+)$/", $filename, $matches)) {
716  $extension = $matches[1];
717  }
718  return md5($filename) . "." . $extension;
719  }
720 
721  protected function cleanImagefiles()
722  {
723  if ($this->getOrderingType() == OQ_PICTURES) {
724  if (@file_exists($this->getImagePath())) {
726  foreach ($contents as $f) {
727  if (strcmp($f['type'], 'file') == 0) {
728  $found = false;
729  foreach ($this->getOrderingElementList() as $orderElement) {
730  if (strcmp($f['entry'], $orderElement->getContent()) == 0) {
731  $found = true;
732  }
733  if (strcmp($f['entry'], $this->getThumbPrefix() . $orderElement->getContent()) == 0) {
734  $found = true;
735  }
736  }
737  if (!$found) {
738  if (@file_exists($this->getImagePath() . $f['entry'])) {
739  @unlink($this->getImagePath() . $f['entry']);
740  }
741  }
742  }
743  }
744  }
745  } else {
746  if (@file_exists($this->getImagePath())) {
747  ilUtil::delDir($this->getImagePath());
748  }
749  }
750  }
751 
752  /*
753  * Deletes an imagefile from the system if the file is deleted manually
754  *
755  * @param string $filename Image file filename
756  * @return boolean Success
757  */
758  public function dropImageFile($imageFilename)
759  {
760  if (!strlen($imageFilename)) {
761  return false;
762  }
763 
764  $result = @unlink($this->getImagePath() . $imageFilename);
765  $result = $result & @unlink($this->getImagePath() . $this->getThumbPrefix() . $imageFilename);
766 
767  return $result;
768  }
769 
770  public function isImageFileStored($imageFilename)
771  {
772  if (!strlen($imageFilename)) {
773  return false;
774  }
775 
776  if (!file_exists($this->getImagePath() . $imageFilename)) {
777  return false;
778  }
779 
780  return is_file($this->getImagePath() . $imageFilename);
781  }
782 
783  public function isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement)
784  {
785  if (!$this->hasOrderingTypeUploadSupport()) {
786  return false;
787  }
788 
789  if (!$newElement->getContent()) {
790  return false;
791  }
792 
793  return $newElement->getContent() != $oldElement->getContent();
794  }
795 
804  public function storeImageFile($uploadFile, $targetFile)
805  {
806  if (!strlen($uploadFile)) {
807  return false;
808  }
809 
810  $this->ensureImagePathExists();
811 
812  // store file with hashed name
813 
814  if (!ilUtil::moveUploadedFile($uploadFile, $targetFile, $this->getImagePath() . $targetFile)) {
815  return false;
816  }
817 
818  return true;
819  }
820 
821  public function handleThumbnailCreation(ilAssOrderingElementList $elementList)
822  {
823  foreach ($elementList as $element) {
824  $this->createImageThumbnail($element);
825  }
826  }
827 
828  public function createImageThumbnail(ilAssOrderingElement $element)
829  {
830  if ($this->getThumbGeometry()) {
831  $imageFile = $this->getImagePath() . $element->getContent();
832  $thumbFile = $this->getImagePath() . $this->getThumbPrefix() . $element->getContent();
833 
834  ilUtil::convertImage($imageFile, $thumbFile, "JPEG", $this->getThumbGeometry());
835  }
836  }
837 
845  public function validateSolutionSubmit()
846  {
847  $submittedSolutionList = $this->getSolutionListFromPostSubmit();
848  return $this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($submittedSolutionList);
849  }
850 
859  public function saveWorkingData($active_id, $pass = null, $authorized = true)
860  {
861  $entered_values = 0;
862 
863  if (is_null($pass)) {
864  include_once "./Modules/Test/classes/class.ilObjTest.php";
865  $pass = ilObjTest::_getPass($active_id);
866  }
867 
868  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(
869  function () use (&$entered_values, $active_id, $pass, $authorized) {
870  $this->removeCurrentSolution($active_id, $pass, $authorized);
871 
872  foreach ($this->getSolutionListFromPostSubmit() as $orderingElement) {
873  $value1 = $orderingElement->getStorageValue1($this->getOrderingType());
874  $value2 = $orderingElement->getStorageValue2($this->getOrderingType());
875 
876  $this->saveCurrentSolution($active_id, $pass, $value1, trim($value2), $authorized);
877 
878  $entered_values++;
879  }
880  }
881  );
882 
883  if ($entered_values) {
884  $this->log($active_id, 'log_user_entered_values');
885  } else {
886  $this->log($active_id, 'log_user_not_entered_values');
887  }
888 
889  return true;
890  }
891 
892  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
893  {
894  if ($this->validateSolutionSubmit()) {
895  $previewSession->setParticipantsSolution(serialize($this->getSolutionListFromPostSubmit()));
896  }
897  }
898 
899  public function saveAdditionalQuestionDataToDb()
900  {
902  global $ilDB;
903 
904  // save additional data
905  $ilDB->manipulateF(
906  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
907  array( "integer" ),
908  array( $this->getId() )
909  );
910 
911  $ilDB->manipulateF(
912  "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, ordering_type, thumb_geometry, element_height)
913  VALUES (%s, %s, %s, %s)",
914  array( "integer", "text", "integer", "integer" ),
915  array(
916  $this->getId(),
917  $this->ordering_type,
918  $this->getThumbGeometry(),
919  ($this->getElementHeight() > 20) ? $this->getElementHeight() : null
920  )
921  );
922  }
923 
924  public function saveAnswerSpecificDataToDb()
925  {
926  $this->getOrderingElementList()->setQuestionId($this->getId());
927  $this->getOrderingElementList()->saveToDb();
928 
929  if ($this->hasOrderingTypeUploadSupport()) {
930  $this->rebuildThumbnails();
931  $this->cleanImagefiles();
932  }
933  }
934 
938  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
939  {
940  // nothing to rework!
941  }
942 
949  public function getQuestionType()
950  {
951  return "assOrderingQuestion";
952  }
953 
960  public function getAdditionalTableName()
961  {
962  return "qpl_qst_ordering";
963  }
964 
971  public function getAnswerTableName()
972  {
973  return "qpl_a_ordering";
974  }
975 
980  public function getRTETextWithMediaObjects()
981  {
982  $text = parent::getRTETextWithMediaObjects();
983 
984  foreach ($this->getOrderingElementList() as $orderingElement) {
985  $text .= $orderingElement->getContent();
986  }
987 
988  return $text;
989  }
990 
995  public function getOrderElements()
996  {
997  return $this->getOrderingElementList()->getRandomIdentifierIndexedElements();
998  }
999 
1006  public function supportsJavascriptOutput()
1007  {
1008  return true;
1009  }
1010 
1011  public function supportsNonJsOutput()
1012  {
1013  return false;
1014  }
1015 
1019  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1020  {
1021  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1022 
1023  $solutions = $this->getSolutionValues($active_id, $pass);
1024  $sol = array();
1025  foreach ($solutions as $solution) {
1026  $sol[$solution["value1"]] = $solution["value2"];
1027  }
1028  asort($sol);
1029  $sol = array_keys($sol);
1030 
1031  $i = 1;
1032  foreach ($sol as $idx) {
1033  foreach ($solutions as $solution) {
1034  if ($solution["value1"] == $idx) {
1035  $worksheet->setCell($startrow + $i, 0, $solution["value2"]);
1036  }
1037  }
1038  $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($idx);
1039  $worksheet->setCell($startrow + $i, 1, $element->getContent());
1040  $i++;
1041  }
1042 
1043  return $startrow + $i + 1;
1044  }
1045 
1046  /*
1047  * Get the thumbnail geometry
1048  *
1049  * @return integer Geometry
1050  */
1051  public function getThumbGeometry()
1052  {
1053  return $this->thumb_geometry;
1054  }
1055 
1056  public function getThumbSize()
1057  {
1058  return $this->getThumbGeometry();
1059  }
1060 
1061  /*
1062  * Set the thumbnail geometry
1063  *
1064  * @param integer $a_geometry Geometry
1065  */
1066  public function setThumbGeometry($a_geometry)
1067  {
1068  $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1069  }
1070 
1071  /*
1072  * Get the minimum element height
1073  *
1074  * @return integer Height
1075  */
1076  public function getElementHeight()
1077  {
1078  return $this->element_height;
1079  }
1080 
1081  /*
1082  * Set the minimum element height
1083  *
1084  * @param integer $a_height Height
1085  */
1086  public function setElementHeight($a_height)
1087  {
1088  $this->element_height = ($a_height < 20) ? "" : $a_height;
1089  }
1090 
1091  /*
1092  * Rebuild the thumbnail images with a new thumbnail size
1093  */
1094  public function rebuildThumbnails()
1095  {
1096  if ($this->getOrderingType() == OQ_PICTURES || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1097  foreach ($this->getOrderElements() as $orderingElement) {
1098  $this->generateThumbForFile($this->getImagePath(), $orderingElement->getContent());
1099  }
1100  }
1101  }
1102 
1103  public function getThumbPrefix()
1104  {
1105  return "thumb.";
1106  }
1107 
1108  protected function generateThumbForFile($path, $file)
1109  {
1110  $filename = $path . $file;
1111  if (@file_exists($filename)) {
1112  $thumbpath = $path . $this->getThumbPrefix() . $file;
1113  $path_info = @pathinfo($filename);
1114  $ext = "";
1115  switch (strtoupper($path_info['extension'])) {
1116  case 'PNG':
1117  $ext = 'PNG';
1118  break;
1119  case 'GIF':
1120  $ext = 'GIF';
1121  break;
1122  default:
1123  $ext = 'JPEG';
1124  break;
1125  }
1126  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1127  }
1128  }
1129 
1133  public function toJSON()
1134  {
1135  include_once("./Services/RTE/classes/class.ilRTE.php");
1136  $result = array();
1137  $result['id'] = (int) $this->getId();
1138  $result['type'] = (string) $this->getQuestionType();
1139  $result['title'] = (string) $this->getTitle();
1140  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1141  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1142  $result['shuffle'] = (bool) true;
1143  $result['points'] = $this->getPoints();
1144  $result['feedback'] = array(
1145  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1146  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1147  );
1148  if ($this->getOrderingType() == OQ_PICTURES) {
1149  $result['path'] = $this->getImagePathWeb();
1150  }
1151 
1152  $counter = 1;
1153  $answers = array();
1154  foreach ($this->getOrderingElementList() as $orderingElement) {
1155  $answers[$counter] = $orderingElement->getContent();
1156  $counter++;
1157  }
1158  $answers = $this->getShuffler()->shuffle($answers);
1159  $arr = array();
1160  foreach ($answers as $order => $answer) {
1161  array_push($arr, array(
1162  "answertext" => (string) $answer,
1163  "order" => (int) $order
1164  ));
1165  }
1166  $result['answers'] = $arr;
1167 
1168  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1169  $result['mobs'] = $mobs;
1170 
1171  return json_encode($result);
1172  }
1173 
1179  {
1180  switch ($this->getOrderingType()) {
1181  case OQ_TERMS:
1182 
1183  return $this->buildOrderingTextsInputGui();
1184 
1185  case OQ_PICTURES:
1186 
1187  return $this->buildOrderingImagesInputGui();
1188 
1189  case OQ_NESTED_TERMS:
1190  case OQ_NESTED_PICTURES:
1191 
1192  return $this->buildNestedOrderingElementInputGui();
1193 
1194  default:
1195  throw new ilTestQuestionPoolException('unknown ordering mode');
1196  }
1197  }
1198 
1203  {
1204  switch (true) {
1205  case $formField instanceof ilAssNestedOrderingElementsInputGUI:
1206 
1207  $formField->setInteractionEnabled(true);
1208  $formField->setNestingEnabled($this->isOrderingTypeNested());
1209  break;
1210 
1211  case $formField instanceof ilAssOrderingTextsInputGUI:
1212  case $formField instanceof ilAssOrderingImagesInputGUI:
1213  default:
1214 
1215  $formField->setEditElementOccuranceEnabled(true);
1216  $formField->setEditElementOrderEnabled(true);
1217  }
1218 
1219  $formField->setRequired(true);
1220  }
1221 
1226  {
1227  $formField->setInfo($this->lng->txt('ordering_answer_sequence_info'));
1228  $formField->setTitle($this->lng->txt('answers'));
1229  }
1230 
1234  public function buildOrderingTextsInputGui()
1235  {
1236  $formDataConverter = $this->buildOrderingTextsFormDataConverter();
1237 
1238  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingTextsInputGUI.php';
1239 
1240  $orderingElementInput = new ilAssOrderingTextsInputGUI(
1241  $formDataConverter,
1242  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1243  );
1244 
1245  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1246 
1247  return $orderingElementInput;
1248  }
1249 
1254  {
1255  $formDataConverter = $this->buildOrderingImagesFormDataConverter();
1256 
1257  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingImagesInputGUI.php';
1258 
1259  $orderingElementInput = new ilAssOrderingImagesInputGUI(
1260  $formDataConverter,
1261  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1262  );
1263 
1264  $orderingElementInput->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1265  $orderingElementInput->setImageUploadCommand(self::ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG);
1266 
1267  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1268 
1269  return $orderingElementInput;
1270  }
1271 
1276  {
1277  $formDataConverter = $this->buildNestedOrderingFormDataConverter();
1278 
1279  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php';
1280 
1281  $orderingElementInput = new ilAssNestedOrderingElementsInputGUI(
1282  $formDataConverter,
1283  self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1284  );
1285 
1286  $orderingElementInput->setUniquePrefix($this->getId());
1287  $orderingElementInput->setOrderingType($this->getOrderingType());
1288  $orderingElementInput->setElementImagePath($this->getImagePathWeb());
1289  $orderingElementInput->setThumbPrefix($this->getThumbPrefix());
1290 
1291  $this->initOrderingElementFormFieldLabels($orderingElementInput);
1292 
1293  return $orderingElementInput;
1294  }
1295 
1301  {
1302  return $form->getItemByPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR)->getElementList($this->getId());
1303  }
1304 
1310  public function fetchSolutionListFromFormSubmissionData($userSolutionPost)
1311  {
1312  $orderingGUI = $this->buildNestedOrderingElementInputGui();
1314  $orderingGUI->setValueByArray($userSolutionPost);
1315 
1316  if (!$orderingGUI->checkInput()) {
1317  require_once 'Modules/Test/exceptions/class.ilTestException.php';
1318  throw new ilTestException('error on validating user solution post');
1319  }
1320 
1321  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssOrderingElementList.php';
1322  $solutionOrderingElementList = ilAssOrderingElementList::buildInstance($this->getId());
1323 
1324  $storedElementList = $this->getOrderingElementList();
1325 
1326  foreach ($orderingGUI->getElementList($this->getId()) as $submittedElement) {
1327  $solutionElement = $storedElementList->getElementByRandomIdentifier(
1328  $submittedElement->getRandomIdentifier()
1329  )->getClone();
1330 
1331  $solutionElement->setPosition($submittedElement->getPosition());
1332 
1333  if ($this->isOrderingTypeNested()) {
1334  $solutionElement->setIndentation($submittedElement->getIndentation());
1335  }
1336 
1337  $solutionOrderingElementList->addElement($solutionElement);
1338  }
1339 
1340  return $solutionOrderingElementList;
1341  }
1342 
1347 
1352  {
1353  if ($this->postSolutionOrderingElementList === null) {
1355  $this->postSolutionOrderingElementList = $list;
1356  }
1357 
1359  }
1360 
1364  public function getSolutionPostSubmit()
1365  {
1366  return $this->fetchSolutionSubmit($_POST);
1367  }
1368 
1374  protected function calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList)
1375  {
1376  $reachedPoints = $this->getPoints();
1377 
1378  foreach ($this->getOrderingElementList() as $correctElement) {
1379  $userElement = $solutionOrderingElementList->getElementByPosition($correctElement->getPosition());
1380 
1381  if (!$correctElement->isSameElement($userElement)) {
1382  $reachedPoints = 0;
1383  break;
1384  }
1385  }
1386 
1387  return $reachedPoints;
1388  }
1389 
1390  /***
1391  * @param object $child
1392  * @param integer $ordering_depth
1393  * @param bool $with_random_id
1394  */
1395  public function getLeveledOrdering()
1396  {
1397  return $this->leveled_ordering;
1398  }
1399 
1400  public function getOldLeveledOrdering()
1401  {
1402  global $ilDB;
1403 
1404  $res = $ilDB->queryF(
1405  'SELECT depth FROM qpl_a_ordering WHERE question_fi = %s ORDER BY position ASC',
1406  array('integer'),
1407  array($this->getId())
1408  );
1409  while ($row = $ilDB->fetchAssoc($res)) {
1410  $this->old_ordering_depth[] = $row['depth'];
1411  }
1413  }
1414 
1415  /***
1416  * @param integer $a_random_id
1417  * @return integer
1418  */
1419  public function lookupSolutionOrderByRandomid($a_random_id)
1420  {
1421  global $ilDB;
1422 
1423  $res = $ilDB->queryF(
1424  'SELECT solution_key FROM qpl_a_ordering WHERE random_id = %s',
1425  array('integer'),
1426  array($a_random_id)
1427  );
1428  $row = $ilDB->fetchAssoc($res);
1429 
1430  return $row['solution_key'];
1431  }
1432 
1433  public function updateLeveledOrdering($a_index, $a_answer_text, $a_depth)
1434  {
1435  global $ilDB;
1436 
1437  $ilDB->update(
1438  'qpl_a_ordering',
1439  array('solution_key'=> array('integer', $a_index),
1440  'depth' => array('integer', $a_depth)),
1441  array('answertext' => array('text', $a_answer_text))
1442  );
1443 
1444 
1445  return true;
1446  }
1447 
1456  public function getOperators($expression)
1457  {
1458  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1460  }
1461 
1466  public function getExpressionTypes()
1467  {
1468  return array(
1473  );
1474  }
1475 
1484  public function getUserQuestionResult($active_id, $pass)
1485  {
1487  global $ilDB;
1488  $result = new ilUserQuestionResult($this, $active_id, $pass);
1489 
1490  $maxStep = $this->lookupMaxStep($active_id, $pass);
1491 
1492  if ($maxStep !== null) {
1493  $data = $ilDB->queryF(
1494  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY value1 ASC ",
1495  array("integer", "integer", "integer","integer"),
1496  array($active_id, $pass, $this->getId(), $maxStep)
1497  );
1498  } else {
1499  $data = $ilDB->queryF(
1500  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY value1 ASC ",
1501  array("integer", "integer", "integer"),
1502  array($active_id, $pass, $this->getId())
1503  );
1504  }
1505 
1506  $elements = array();
1507  while ($row = $ilDB->fetchAssoc($data)) {
1508  $newKey = explode(":", $row["value2"]);
1509 
1510  foreach ($this->getOrderingElementList() as $answer) {
1511  // Images nut supported
1512  if (!$this->isOrderingTypeNested()) {
1513  if ($answer->getSolutionIdentifier() == $row["value1"]) {
1514  $elements[$row["value2"]] = $answer->getSolutionIdentifier() + 1;
1515  break;
1516  }
1517  } else {
1518  if ($answer->getRandomIdentifier() == $newKey[0]) {
1519  $elements[$row["value1"]] = $answer->getSolutionIdentifier() + 1;
1520  break;
1521  }
1522  }
1523  }
1524  }
1525 
1526  ksort($elements);
1527 
1528  foreach (array_values($elements) as $element) {
1529  $result->addKeyValue($element, $element);
1530  }
1531 
1532  $points = $this->calculateReachedPoints($active_id, $pass);
1533  $max_points = $this->getMaximumPoints();
1534 
1535  $result->setReachedPercentage(($points/$max_points) * 100);
1536 
1537  return $result;
1538  }
1539 
1548  public function getAvailableAnswerOptions($index = null)
1549  {
1550  if ($index !== null) {
1551  return $this->getOrderingElementList()->getElementByPosition($index);
1552  }
1553 
1554  return $this->getOrderingElementList()->getElements();
1555  }
1556 
1560  protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1561  {
1562  parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1563  $this->duplicateImages($dupQuestionId, $dupParentObjId, $origQuestionId, $origParentObjId);
1564  }
1565 
1566  // fau: testNav - new function getTestQuestionConfig()
1571  // hey: refactored identifiers
1573  // hey.
1574  {
1575  // hey: refactored identifiers
1576  return parent::buildTestPresentationConfig()
1577  // hey.
1578  ->setIsUnchangedAnswerPossible(true)
1579  ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
1580  }
1581  // fau.
1582 
1583  protected function ensureImagePathExists()
1584  {
1585  if (!file_exists($this->getImagePath())) {
1587  }
1588  }
1589 
1593  public function fetchSolutionSubmit($formSubmissionDataStructure)
1594  {
1595  $solutionSubmit = array();
1596 
1597  if (isset($formSubmissionDataStructure['orderresult'])) {
1598  $orderresult = $formSubmissionDataStructure['orderresult'];
1599 
1600  if (strlen($orderresult)) {
1601  $orderarray = explode(":", $orderresult);
1602  $ordervalue = 1;
1603  foreach ($orderarray as $index) {
1604  $idmatch = null;
1605  if (preg_match("/id_(\\d+)/", $index, $idmatch)) {
1606  $randomid = $idmatch[1];
1607  foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1608  if ($answer->getRandomIdentifier() == $randomid) {
1609  $solutionSubmit[$answeridx] = $ordervalue;
1610  $ordervalue++;
1611  }
1612  }
1613  }
1614  }
1615  }
1616  } elseif ($this->getOrderingType() == OQ_NESTED_TERMS || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1617  $index = 0;
1618  foreach ($formSubmissionDataStructure['content'] as $randomId => $content) {
1619  $indentation = $formSubmissionDataStructure['indentation'];
1620 
1621  $value1 = $index++;
1622  $value2 = implode(':', array($randomId, $indentation));
1623 
1624  $solutionSubmit[$value1] = $value2;
1625  }
1626  } else {
1627  foreach ($formSubmissionDataStructure as $key => $value) {
1628  $matches = null;
1629  if (preg_match("/^order_(\d+)/", $key, $matches)) {
1630  if (!(preg_match("/initial_value_\d+/", $value))) {
1631  if (strlen($value)) {
1632  foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1633  if ($answer->getRandomIdentifier() == $matches[1]) {
1634  $solutionSubmit[$answeridx] = $value;
1635  }
1636  }
1637  }
1638  }
1639  }
1640  }
1641  }
1642 
1643  return $solutionSubmit;
1644  }
1645 
1650  {
1651  require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingFormValuesObjectsConverter.php';
1652  $converter = new ilAssOrderingFormValuesObjectsConverter();
1653  $converter->setPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR);
1654 
1655  return $converter;
1656  }
1657 
1662  {
1663  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1665 
1666  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1667  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1668  $formDataConverter->setImageFsPath($this->getImagePath());
1669 
1670  if ($this->getThumbSize() && $this->getThumbPrefix()) {
1671  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1672  }
1673  return $formDataConverter;
1674  }
1675 
1680  {
1681  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1683  return $formDataConverter;
1684  }
1685 
1690  {
1691  $formDataConverter = $this->buildOrderingElementFormDataConverter();
1693 
1694  if ($this->getOrderingType() == OQ_NESTED_PICTURES) {
1695  $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1696  $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1697 
1698  if ($this->getThumbSize() && $this->getThumbPrefix()) {
1699  $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1700  }
1701  }
1702 
1703  return $formDataConverter;
1704  }
1705 }
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.
Add rich text string
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
$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.
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)
getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex)
$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.
$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.
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.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{}
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
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)
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.
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)
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
$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.
getAnswerCount()
Returns the number of answers.