ILIAS  release_8 Revision v8.24
class.assOrderingQuestion.php
Go to the documentation of this file.
1<?php
2
19require_once './Modules/Test/classes/inc.AssessmentConstants.php';
20
22
38{
39 public const ORDERING_ELEMENT_FORM_FIELD_POSTVAR = 'order_elems';
40
41 public const ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG = 'uploadElementImage';
42 public const ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG = 'removeElementImage'; //might actually go away - use ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG
43
44 public const OQ_PICTURES = 0;
45 public const OQ_TERMS = 1;
46 public const OQ_NESTED_PICTURES = 2;
47 public const OQ_NESTED_TERMS = 3;
48
49 public const OQ_CT_PICTURES = 'pics';
50 public const OQ_CT_TERMS = 'terms';
51
52 public const VALID_UPLOAD_SUFFIXES = ["jpg", "jpeg", "png", "gif"];
53
54 protected const HAS_SPECIFIC_FEEDBACK = false;
55
56
61
66 protected $ordering_type;
67
68 public ?int $element_height = null;
69
70 public $old_ordering_depth = array();
71 public $leveled_ordering = array();
72
76 protected $oq_repository = null;
77
90 public function __construct(
91 $title = "",
92 $comment = "",
93 $author = "",
94 $owner = -1,
95 $question = "",
97 ) {
99 $this->orderingElementList = new ilAssOrderingElementList();
100 $this->ordering_type = $ordering_type;
101 }
102
108 public function isComplete(): bool
109 {
110 $elements = array_filter(
111 $this->getOrderingElementList()->getElements(),
112 fn ($element) => trim($element->getContent()) != ''
113 );
114 $has_at_least_two_elements = count($elements) > 1;
115
116 $complete = $this->getAuthor()
117 && $this->getTitle()
118 && $this->getQuestion()
119 && $this->getMaximumPoints()
120 && $has_at_least_two_elements;
121
122 return $complete;
123 }
124
125
126
127 protected function getRepository(): ILIAS\TA\Questions\Ordering\assOrderingQuestionDatabaseRepository
128 {
129 if (is_null($this->oq_repository)) {
130 global $DIC;
131 $ilDB = $DIC['ilDB'];
132 $this->oq_repository = new OQRepository($ilDB);
133 }
135 }
136
137
145 public function saveToDb($original_id = ""): void
146 {
147 if ($original_id == '') {
148 $this->saveQuestionDataToDb();
149 } else {
151 }
153 parent::saveToDb();
154 }
155
163 public function loadFromDb($question_id): void
164 {
165 global $DIC;
166 $ilDB = $DIC['ilDB'];
167
168 $result = $ilDB->queryF(
169 "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",
170 array("integer"),
171 array($question_id)
172 );
173 if ($result->numRows() == 1) {
174 $data = $ilDB->fetchAssoc($result);
175 $this->setId($question_id);
176 $this->setObjId($data["obj_fi"]);
177 $this->setTitle((string) $data["title"]);
178 $this->setComment((string) $data["description"]);
179 $this->setOriginalId($data["original_id"]);
180 $this->setAuthor($data["author"]);
181 $this->setNrOfTries($data['nr_of_tries']);
182 $this->setPoints($data["points"]);
183 $this->setOwner($data["owner"]);
184 include_once("./Services/RTE/classes/class.ilRTE.php");
185 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc((string) $data["question_text"], 1));
186 $this->ordering_type = $data["ordering_type"] !== null ? (int) $data["ordering_type"] : OQ_TERMS;
187 if ($data['thumb_geometry'] !== null && $data['thumb_geometry'] >= $this->getMinimumThumbSize()) {
188 $this->setThumbSize($data['thumb_geometry']);
189 }
190 $this->element_height = $data["element_height"] ? (int) $data['element_height'] : null;
191
192 try {
193 $this->setLifecycle(ilAssQuestionLifecycle::getInstance($data['lifecycle']));
196 }
197
198 try {
199 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
201 }
202 }
203
204 parent::loadFromDb($question_id);
205 }
206
207 public function duplicate(
208 bool $for_test = true,
209 ?string $title = "",
210 ?string $author = "",
211 ?string $owner = "",
212 $testObjId = null
213 ): int {
214 if ($this->id <= 0) {
215 // The question has not been saved. It cannot be duplicated
216 return -1;
217 }
218 // duplicate the question in database
219 $this_id = $this->getId();
220 $thisObjId = $this->getObjId();
221
222 $clone = clone $this;
224 $clone->id = -1;
225
226 if ((int) $testObjId > 0) {
227 $clone->setObjId($testObjId);
228 }
229
230 if ($title) {
231 $clone->setTitle($title);
232 }
233 if ($author) {
234 $clone->setAuthor($author);
235 }
236 if ($owner) {
237 $clone->setOwner($owner);
238 }
239 if ($for_test) {
240 $clone->saveToDb($original_id);
241 } else {
242 $clone->saveToDb();
243 }
244
245 //$list = $this->getRepository()->getOrderingList($original_id)
246 $list = $this->getRepository()->getOrderingList($this_id)
247 ->withQuestionId($clone->getId());
248 $list->distributeNewRandomIdentifiers();
249 $clone->setOrderingElementList($list);
250 $clone->saveToDb();
251
252 $clone->copyPageOfQuestion($this_id);
253 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
254 $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
255
256 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
257 return $clone->getId();
258 }
259
265 public function copyObject($target_questionpool_id, $title = ""): int
266 {
267 if ($this->getId() <= 0) {
268 throw new RuntimeException('The question has not been saved. It cannot be duplicated');
269 }
270 // duplicate the question in database
271 $clone = clone $this;
272 $this_id = $this->getId();
273 $original_id = assQuestion::_getOriginalId($this_id);
274 $clone->id = -1;
275 $source_questionpool_id = $this->getObjId();
276 $clone->setObjId($target_questionpool_id);
277 if ($title) {
278 $clone->setTitle($title);
279 }
280 $clone->saveToDb();
281
282 $list = $this->getRepository()->getOrderingList($this_id)
283 ->withQuestionId($clone->getId());
284 $list->distributeNewRandomIdentifiers();
285 $clone->setOrderingElementList($list);
286 $clone->saveToDb();
287
288 $clone->copyPageOfQuestion($original_id);
289 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
290 $clone->duplicateImages($original_id, $source_questionpool_id, $clone->getId(), $target_questionpool_id);
291
292 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
293
294 return $clone->getId();
295 }
296
297 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = ""): int
298 {
299 if ($this->getId() <= 0) {
300 throw new RuntimeException('The question has not been saved. It cannot be duplicated');
301 }
302
303 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
304
305 $sourceQuestionId = $this->id;
306 $sourceParentId = $this->getObjId();
307
308 // duplicate the question in database
309 $clone = clone $this;
310 $clone->id = -1;
311
312 $clone->setObjId($targetParentId);
313
314 if ($targetQuestionTitle) {
315 $clone->setTitle($targetQuestionTitle);
316 }
317
318 $clone->saveToDb();
319
320 $list = $this->getRepository()->getOrderingList($this->getId())
321 ->withQuestionId($clone->getId());
322 $list->distributeNewRandomIdentifiers();
323 $clone->setOrderingElementList($list);
324 $clone->saveToDb();
325
326 // copy question page content
327 $clone->copyPageOfQuestion($sourceQuestionId);
328 // copy XHTML media objects
329 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
330 // duplicate the image
331 $clone->duplicateImages($sourceQuestionId, $sourceParentId, $clone->getId(), $clone->getObjId());
332
333 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
334
335 return $clone->id;
336 }
337
338 public function duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id): void
339 {
340 global $DIC;
341 $ilLog = $DIC['ilLog'];
342 if ($this->isImageOrderingType()) {
343 $imagepath_original = $this->getImagePath($src_question_id, $src_object_id);
344 $imagepath = $this->getImagePath($dest_question_id, $dest_object_id);
345
346 if (!file_exists($imagepath)) {
347 ilFileUtils::makeDirParents($imagepath);
348 }
349 foreach ($this->getOrderingElementList() as $element) {
350 $filename = $element->getContent();
351
352 if ($filename === '') {
353 continue;
354 }
355
356 if (!file_exists($imagepath_original . $filename)
357 || !copy($imagepath_original . $filename, $imagepath . $filename)) {
358 $ilLog->write("image could not be duplicated!!!!");
359 $ilLog->write($imagepath_original . $filename);
360 $ilLog->write($imagepath . $filename);
361 }
362 if (file_exists($imagepath_original . $this->getThumbPrefix() . $filename)
363 && !copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
364 $ilLog->write("image thumbnail could not be duplicated!!!!");
365 }
366 }
367 }
368 }
369
375 public function copyImages($question_id, $source_questionpool): void
376 {
377 global $DIC;
378 $ilLog = $DIC['ilLog'];
379 if ($this->getOrderingType() == OQ_PICTURES) {
380 $imagepath = $this->getImagePath();
381 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
382 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
383 if (!file_exists($imagepath)) {
384 ilFileUtils::makeDirParents($imagepath);
385 }
386 foreach ($this->getOrderingElementList() as $element) {
387 $filename = $element->getContent();
388 if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
389 $ilLog->write("Ordering Question image could not be copied: ${imagepath_original}${filename}");
390 }
391 if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
392 if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
393 $ilLog->write("Ordering Question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
394 }
395 }
396 }
397 }
398 }
399
400 protected function getValidOrderingTypes(): array
401 {
402 return [
407 ];
408 }
409
410 public function setOrderingType($ordering_type = self::OQ_TERMS)
411 {
412 if (!in_array($ordering_type, $this->getValidOrderingTypes())) {
413 throw new \InvalidArgumentException('Must be valid ordering type.');
414 }
415 $this->ordering_type = $ordering_type;
416 }
417
418 public function getOrderingType(): int
419 {
420 return $this->ordering_type;
421 }
422
423 public function isOrderingTypeNested(): bool
424 {
425 $nested = [
428 ];
429 return in_array($this->getOrderingType(), $nested);
430 }
431
432 public function isImageOrderingType(): bool
433 {
434 $with_images = [
437 ];
438 return in_array($this->getOrderingType(), $with_images);
439 }
440
441 public function setContentType($ct)
442 {
443 if (!in_array($ct, [
444 self::OQ_CT_PICTURES,
445 self::OQ_CT_TERMS
446 ])) {
447 throw new \InvalidArgumentException("use OQ content-type", 1);
448 }
449 if ($ct == self::OQ_CT_PICTURES) {
450 if ($this->isOrderingTypeNested()) {
451 $this->setOrderingType(self::OQ_NESTED_PICTURES);
452 } else {
453 $this->setOrderingType(self::OQ_PICTURES);
454 }
455 $this->setThumbSize($this->getThumbSize());
456 }
457 if ($ct == self::OQ_CT_TERMS) {
458 if ($this->isOrderingTypeNested()) {
459 $this->setOrderingType(self::OQ_NESTED_TERMS);
460 } else {
461 $this->setOrderingType(self::OQ_TERMS);
462 }
463 }
464 }
465
466 public function setNestingType(bool $nesting)
467 {
468 if ($nesting) {
469 if ($this->isImageOrderingType()) {
470 $this->setOrderingType(self::OQ_NESTED_PICTURES);
471 } else {
472 $this->setOrderingType(self::OQ_NESTED_TERMS);
473 }
474 } else {
475 if ($this->isImageOrderingType()) {
476 $this->setOrderingType(self::OQ_PICTURES);
477 } else {
478 $this->setOrderingType(self::OQ_TERMS);
479 }
480 }
481 }
482
483 public function hasOrderingTypeUploadSupport(): bool
484 {
485 return $this->isImageOrderingType();
486 }
487
494 public function getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex): ilAssOrderingElementList
495 {
496 if ($forceCorrectSolution || !$activeId || $passIndex === null) {
497 return $this->getOrderingElementList();
498 }
499
500 $solutionValues = $this->getSolutionValues($activeId, $passIndex);
501
502 if (!count($solutionValues)) {
503 return $this->getShuffledOrderingElementList();
504 }
505
506 return $this->getSolutionOrderingElementList($this->fetchIndexedValuesFromValuePairs($solutionValues));
507 }
508
519 {
520 if ($inputGUI->isPostSubmit($lastPost)) {
521 return $this->fetchSolutionListFromFormSubmissionData($lastPost);
522 }
523 $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs(
524 // hey: prevPassSolutions - obsolete due to central check
525 $this->getTestOutputSolutions($activeId, $pass)
526 // hey.
527 );
528
529 if (count($indexedSolutionValues)) {
530 return $this->getSolutionOrderingElementList($indexedSolutionValues);
531 }
532
533 return $this->getShuffledOrderingElementList();
534 }
535
541 {
542 $value2 = explode(':', $value2);
543
544 $randomIdentifier = $value2[0];
545 $selectedPosition = $value1;
546 $selectedIndentation = $value2[1];
547
548 $element = $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)->getClone();
549
550 $element->setPosition($selectedPosition);
551 $element->setIndentation($selectedIndentation);
552
553 return $element;
554 }
555
561 {
562 $solutionIdentifier = $value1;
563 $selectedPosition = ($value2 - 1);
564 $selectedIndentation = 0;
565
566 $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($solutionIdentifier)->getClone();
567
568 $element->setPosition($selectedPosition);
569 $element->setIndentation($selectedIndentation);
570
571 return $element;
572 }
573
579 public function getSolutionOrderingElementList($indexedSolutionValues): ilAssOrderingElementList
580 {
581 $solutionOrderingList = new ilAssOrderingElementList();
582 $solutionOrderingList->setQuestionId($this->getId());
583
584 foreach ($indexedSolutionValues as $value1 => $value2) {
585 if ($this->isOrderingTypeNested()) {
586 $element = $this->getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2);
587 } else {
588 $element = $this->getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2);
589 }
590
591 $solutionOrderingList->addElement($element);
592 }
593
594 if (!$this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($solutionOrderingList)) {
595 throw new ilTestQuestionPoolException('inconsistent solution values given');
596 }
597
598 return $solutionOrderingList;
599 }
600
602 {
603 $shuffledRandomIdentifierIndex = $this->getShuffler()->transform(
604 $this->getOrderingElementList()->getRandomIdentifierIndex()
605 );
606
607 $shuffledElementList = $this->getOrderingElementList()->getClone();
608 $shuffledElementList->reorderByRandomIdentifiers($shuffledRandomIdentifierIndex);
609 $shuffledElementList->resetElementsIndentations();
610
611 return $shuffledElementList;
612 }
613
615 {
616 return $this->getRepository()->getOrderingList($this->getId());
617 }
618
620 {
621 $list = $list->withQuestionId($this->getId());
622 $elements = $list->getElements();
623 $nu = [];
624 foreach ($elements as $e) {
625 $nu[] = $list->ensureValidIdentifiers($e);
626 }
627 $list = $list->withElements($nu);
628 $this->getRepository()->updateOrderingList($list);
629 }
630
637 public function getAnswer($index = 0): ?ilAssOrderingElement
638 {
639 if (!$this->getOrderingElementList()->elementExistByPosition($index)) {
640 return null;
641 }
642
643 return $this->getOrderingElementList()->getElementByPosition($index);
644 }
645
654 public function deleteAnswer($randomIdentifier): void
655 {
656 $this->getOrderingElementList()->removeElement(
657 $this->getOrderingElementList()->getElementByRandomIdentifier($randomIdentifier)
658 );
659 $this->getOrderingElementList()->saveToDb();
660 }
661
662 public function getAnswerCount(): int
663 {
664 return $this->getOrderingElementList()->countElements();
665 }
666
677 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
678 {
679 if ($returndetails) {
680 throw new ilTestException('return details not implemented for ' . __METHOD__);
681 }
682
683 if (is_null($pass)) {
684 $pass = $this->getSolutionMaxPass($active_id);
685 }
686
687 $solutionValuePairs = $this->getSolutionValues($active_id, $pass, $authorizedSolution);
688
689 if (!count($solutionValuePairs)) {
690 return 0;
691 }
692
693 $indexedSolutionValues = $this->fetchIndexedValuesFromValuePairs($solutionValuePairs);
694 $solutionOrderingElementList = $this->getSolutionOrderingElementList($indexedSolutionValues);
695
696 return $this->calculateReachedPointsForSolution($solutionOrderingElementList);
697 }
698
700 {
701 if (!$previewSession->hasParticipantSolution()) {
702 return 0;
703 }
704
705 $solutionOrderingElementList = unserialize(
706 $previewSession->getParticipantsSolution(),
707 ["allowed_classes" => true]
708 );
709
710 $reachedPoints = $this->calculateReachedPointsForSolution($solutionOrderingElementList);
711 $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $reachedPoints);
712
713 return $this->ensureNonNegativePoints($reachedPoints);
714 }
715
720 public function getMaximumPoints(): float
721 {
722 return $this->getPoints();
723 }
724
725 /*
726 * Returns the encrypted save filename of a matching picture
727 * Images are saved with an encrypted filename to prevent users from
728 * cheating by guessing the solution from the image filename
729 *
730 * @param string $filename Original filename
731 * @return string Encrypted filename
732 */
733 public function getEncryptedFilename($filename): string
734 {
735 $extension = "";
736 if (preg_match("/.*\\.(\\w+)$/", $filename, $matches)) {
737 $extension = $matches[1];
738 }
739 return md5($filename) . "." . $extension;
740 }
741
742 protected function cleanImagefiles(): void
743 {
744 if ($this->getOrderingType() == self::OQ_PICTURES) {
745 if (@file_exists($this->getImagePath())) {
746 $contents = ilFileUtils::getDir($this->getImagePath());
747 foreach ($contents as $f) {
748 if (strcmp($f['type'], 'file') == 0) {
749 $found = false;
750 foreach ($this->getOrderingElementList() as $orderElement) {
751 if (strcmp($f['entry'], $orderElement->getContent()) == 0) {
752 $found = true;
753 }
754 if (strcmp($f['entry'], $this->getThumbPrefix() . $orderElement->getContent()) == 0) {
755 $found = true;
756 }
757 }
758 if (!$found) {
759 if (@file_exists($this->getImagePath() . $f['entry'])) {
760 @unlink($this->getImagePath() . $f['entry']);
761 }
762 }
763 }
764 }
765 }
766 } else {
767 if (@file_exists($this->getImagePath())) {
768 ilFileUtils::delDir($this->getImagePath());
769 }
770 }
771 }
772
773 /*
774 * Deletes an imagefile from the system if the file is deleted manually
775 * @return boolean Success
776 */
777 public function dropImageFile($imageFilename)
778 {
779 if (!strlen($imageFilename)) {
780 return false;
781 }
782
783 $result = @unlink($this->getImagePath() . $imageFilename);
784 $result = $result && @unlink($this->getImagePath() . $this->getThumbPrefix() . $imageFilename);
785
786 return $result;
787 }
788
789 public function isImageFileStored($imageFilename): bool
790 {
791 if (!strlen($imageFilename)) {
792 return false;
793 }
794
795 if (!file_exists($this->getImagePath() . $imageFilename)) {
796 return false;
797 }
798
799 return is_file($this->getImagePath() . $imageFilename);
800 }
801
802 public function isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement): bool
803 {
804 if (!$this->hasOrderingTypeUploadSupport()) {
805 return false;
806 }
807
808 if (!$newElement->getContent()) {
809 return false;
810 }
811
812 return $newElement->getContent() != $oldElement->getContent();
813 }
814
815 public function storeImageFile(string $upload_file, string $upload_name): ?string
816 {
817 $name_parts = explode(".", $upload_name);
818 $suffix = strtolower(array_pop($name_parts));
819 if (!in_array($suffix, self::VALID_UPLOAD_SUFFIXES)) {
820 return null;
821 }
822
823 $this->ensureImagePathExists();
824 $target_filename = $this->buildHashedImageFilename($upload_name, true);
825 $target_filepath = $this->getImagePath() . $target_filename;
826 if (ilFileUtils::moveUploadedFile($upload_file, $target_filename, $target_filepath)) {
827 $thumb_path = $this->getImagePath() . $this->getThumbPrefix() . $target_filename;
828 ilShellUtil::convertImage($target_filepath, $thumb_path, "JPEG", (string) $this->getThumbSize());
829
830 return $target_filename;
831 }
832
833 return null;
834 }
835
836 public function updateImageFile(string $existing_image_name): ?string
837 {
838 $existing_image_path = $this->getImagePath() . $existing_image_name;
839 $target_filename = $this->buildHashedImageFilename($existing_image_name, true);
840 $target_filepath = $this->getImagePath() . $target_filename;
841 if (ilFileUtils::rename($existing_image_path, $target_filepath)) {
842 unlink($this->getImagePath() . $this->getThumbPrefix() . $existing_image_name);
843 $thumb_path = $this->getImagePath() . $this->getThumbPrefix() . $target_filename;
844 ilShellUtil::convertImage($target_filepath, $thumb_path, "JPEG", (string) $this->getThumbSize());
845
846 return $target_filename;
847 }
848
849 return $existing_image_name;
850 }
851
852 public function validateSolutionSubmit(): bool
853 {
854 $submittedSolutionList = $this->getSolutionListFromPostSubmit();
855
856 if (!$submittedSolutionList->hasElements()) {
857 return true;
858 }
859
860 return $this->getOrderingElementList()->hasSameElementSetByRandomIdentifiers($submittedSolutionList);
861 }
862
871 public function saveWorkingData($active_id, $pass = null, $authorized = true): bool
872 {
873 global $DIC;
874 if ($DIC->testQuestionPool()->internal()->request()->raw('test_answer_changed') === null) {
875 return true;
876 }
877
878 $entered_values = 0;
879
880 if (is_null($pass)) {
881 $pass = ilObjTest::_getPass($active_id);
882 }
883
884 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(
885 function () use (&$entered_values, $active_id, $pass, $authorized) {
886 $this->removeCurrentSolution($active_id, $pass, $authorized);
887
888 foreach ($this->getSolutionListFromPostSubmit() as $orderingElement) {
889 $value1 = $orderingElement->getStorageValue1($this->getOrderingType());
890 $value2 = $orderingElement->getStorageValue2($this->getOrderingType());
891
892 $this->saveCurrentSolution($active_id, $pass, $value1, trim($value2), $authorized);
893
894 $entered_values++;
895 }
896 }
897 );
898
899 if ($entered_values) {
900 $this->log($active_id, 'log_user_entered_values');
901 } else {
902 $this->log($active_id, 'log_user_not_entered_values');
903 }
904
905 return true;
906 }
907
908 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession): void
909 {
910 if ($this->validateSolutionSubmit()) {
911 $previewSession->setParticipantsSolution(serialize($this->getSolutionListFromPostSubmit()));
912 }
913 }
914
915 public function saveAdditionalQuestionDataToDb()
916 {
918 global $DIC;
919 $ilDB = $DIC['ilDB'];
920
921 // save additional data
922 $ilDB->manipulateF(
923 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
924 ["integer"],
925 [$this->getId()]
926 );
927
928 $ilDB->manipulateF(
929 "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, ordering_type, thumb_geometry, element_height)
930 VALUES (%s, %s, %s, %s)",
931 ["integer", "text", "integer", "integer"],
932 [
933 $this->getId(),
934 $this->ordering_type,
935 $this->getThumbSize(),
936 ($this->getElementHeight() > 20) ? $this->getElementHeight() : null
937 ]
938 );
939 }
940
941 protected function getQuestionRepository(): ILIAS\TA\Questions\Ordering\assOrderingQuestionDatabaseRepository
942 {
943 global $DIC;
944 $ilDB = $DIC['ilDB'];
945 return new \ILIAS\TA\Questions\Ordering\assOrderingQuestionDatabaseRepository($ilDB);
946 }
947
949 {
950 }
951
952 public function getQuestionType(): string
953 {
954 return "assOrderingQuestion";
955 }
956
957 public function getAdditionalTableName(): string
958 {
959 return "qpl_qst_ordering";
960 }
961
968 public function getAnswerTableName(): string
969 {
970 return "qpl_a_ordering";
971 }
972
977 public function getRTETextWithMediaObjects(): string
978 {
979 $text = parent::getRTETextWithMediaObjects();
980
981 foreach ($this->getOrderingElementList() as $orderingElement) {
982 $text .= $orderingElement->getContent();
983 }
984
985 return $text;
986 }
987
992 public function getOrderElements(): array
993 {
994 return $this->getOrderingElementList()->getRandomIdentifierIndexedElements();
995 }
996
1003 public function supportsJavascriptOutput(): bool
1004 {
1005 return true;
1006 }
1007
1008 public function supportsNonJsOutput(): bool
1009 {
1010 return false;
1011 }
1012
1016 public function setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass): int
1017 {
1018 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1019
1020 $solutions = $this->getSolutionValues($active_id, $pass);
1021 $sol = array();
1022 foreach ($solutions as $solution) {
1023 $sol[$solution["value1"]] = $solution["value2"];
1024 }
1025 asort($sol);
1026 $sol = array_keys($sol);
1027
1028 $i = 1;
1029 foreach ($sol as $idx) {
1030 foreach ($solutions as $solution) {
1031 if ($solution["value1"] == $idx) {
1032 $worksheet->setCell($startrow + $i, 0, $solution["value2"]);
1033 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
1034 }
1035 }
1036 $element = $this->getOrderingElementList()->getElementBySolutionIdentifier($idx);
1037 $worksheet->setCell($startrow + $i, 2, $element->getContent());
1038 $i++;
1039 }
1040
1041 return $startrow + $i + 1;
1042 }
1043
1044 public function getElementHeight(): ?int
1045 {
1046 return $this->element_height;
1047 }
1048
1049 public function setElementHeight(?int $a_height): void
1050 {
1051 $this->element_height = ($a_height < 20) ? null : $a_height;
1052 }
1053
1054 /*
1055 * Rebuild the thumbnail images with a new thumbnail size
1056 */
1057 public function rebuildThumbnails(): void
1058 {
1059 if ($this->isImageOrderingType()) {
1060 foreach ($this->getOrderElements() as $orderingElement) {
1061 if ($orderingElement->getContent() !== '') {
1062 $this->generateThumbForFile($this->getImagePath(), $orderingElement->getContent());
1063 }
1064 }
1065 }
1066 }
1067
1068 public function getThumbPrefix(): string
1069 {
1070 return "thumb.";
1071 }
1072
1073 protected function generateThumbForFile($path, $file): void
1074 {
1075 $filename = $path . $file;
1076 if (@file_exists($filename)) {
1077 $thumbpath = $path . $this->getThumbPrefix() . $file;
1078 $path_info = @pathinfo($filename);
1079 $ext = "";
1080 switch (strtoupper($path_info['extension'])) {
1081 case 'PNG':
1082 $ext = 'PNG';
1083 break;
1084 case 'GIF':
1085 $ext = 'GIF';
1086 break;
1087 default:
1088 $ext = 'JPEG';
1089 break;
1090 }
1091 ilShellUtil::convertImage($filename, $thumbpath, $ext, (string) $this->getThumbSize());
1092 }
1093 }
1094
1098 public function toJSON(): string
1099 {
1100 include_once("./Services/RTE/classes/class.ilRTE.php");
1101 $result = array();
1102 $result['id'] = $this->getId();
1103 $result['type'] = (string) $this->getQuestionType();
1104 $result['title'] = $this->getTitleForHTMLOutput();
1105 $result['question'] = $this->formatSAQuestion($this->getQuestion());
1106 $result['nr_of_tries'] = $this->getNrOfTries();
1107 $result['shuffle'] = true;
1108 $result['points'] = $this->getPoints();
1109 $result['feedback'] = array(
1110 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1111 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1112 );
1113 if ($this->getOrderingType() == self::OQ_PICTURES) {
1114 $result['path'] = $this->getImagePathWeb();
1115 }
1116
1117 $counter = 1;
1118 $answers = array();
1119 foreach ($this->getOrderingElementList() as $orderingElement) {
1120 $answers[$counter] = $orderingElement->getContent();
1121 $counter++;
1122 }
1123 $answers = $this->getShuffler()->transform($answers);
1124 $arr = array();
1125 foreach ($answers as $order => $answer) {
1126 array_push($arr, array(
1127 "answertext" => (string) $answer,
1128 "order" => (int) $order
1129 ));
1130 }
1131 $result['answers'] = $arr;
1132
1133 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1134 $result['mobs'] = $mobs;
1135
1136 return json_encode($result);
1137 }
1138
1144 {
1145 if ($this->isImageOrderingType()) {
1146 return $this->buildOrderingImagesInputGui();
1147 }
1148 return $this->buildOrderingTextsInputGui();
1149 }
1150
1152 {
1153 switch (true) {
1154 case $formField instanceof ilAssNestedOrderingElementsInputGUI:
1155 $formField->setInteractionEnabled(true);
1156 $formField->setNestingEnabled($this->isOrderingTypeNested());
1157 break;
1158
1159 case $formField instanceof ilAssOrderingTextsInputGUI:
1160 case $formField instanceof ilAssOrderingImagesInputGUI:
1161 default:
1162
1163 $formField->setEditElementOccuranceEnabled(true);
1164 $formField->setEditElementOrderEnabled(true);
1165 }
1166 }
1167
1169 {
1170 $formField->setInfo($this->lng->txt('ordering_answer_sequence_info'));
1171 $formField->setTitle($this->lng->txt('answers'));
1172 }
1173
1175 {
1176 $formDataConverter = $this->buildOrderingTextsFormDataConverter();
1177
1178 $orderingElementInput = new ilAssOrderingTextsInputGUI(
1179 $formDataConverter,
1180 self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1181 );
1182
1183 $this->initOrderingElementFormFieldLabels($orderingElementInput);
1184
1185 return $orderingElementInput;
1186 }
1187
1189 {
1190 $formDataConverter = $this->buildOrderingImagesFormDataConverter();
1191
1192 $orderingElementInput = new ilAssOrderingImagesInputGUI(
1193 $formDataConverter,
1194 self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1195 );
1196
1197 $orderingElementInput->setImageUploadCommand(self::ORDERING_ELEMENT_FORM_CMD_UPLOAD_IMG);
1198 $orderingElementInput->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1199
1200 $this->initOrderingElementFormFieldLabels($orderingElementInput);
1201
1202 return $orderingElementInput;
1203 }
1204
1209 {
1210 $formDataConverter = $this->buildNestedOrderingFormDataConverter();
1211
1212 $orderingElementInput = new ilAssNestedOrderingElementsInputGUI(
1213 $formDataConverter,
1214 self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR
1215 );
1216
1217 $orderingElementInput->setUniquePrefix($this->getId());
1218 $orderingElementInput->setOrderingType($this->getOrderingType());
1219 $orderingElementInput->setElementImagePath($this->getImagePathWeb());
1220 $orderingElementInput->setThumbPrefix($this->getThumbPrefix());
1221
1222 $this->initOrderingElementFormFieldLabels($orderingElementInput);
1223
1224 return $orderingElementInput;
1225 }
1226
1227
1232 {
1233 $orderingGUI = $this->buildNestedOrderingElementInputGui();
1235 $orderingGUI->setValueByArray($userSolutionPost);
1236
1237 if (!$orderingGUI->checkInput()) {
1238 throw new ilTestException('error on validating user solution post');
1239 }
1240
1241 $solutionOrderingElementList = ilAssOrderingElementList::buildInstance($this->getId());
1242
1243 $storedElementList = $this->getOrderingElementList();
1244
1245 foreach ($orderingGUI->getElementList($this->getId()) as $submittedElement) {
1246 $solutionElement = $storedElementList->getElementByRandomIdentifier(
1247 $submittedElement->getRandomIdentifier()
1248 )->getClone();
1249
1250 $solutionElement->setPosition($submittedElement->getPosition());
1251
1252 if ($this->isOrderingTypeNested()) {
1253 $solutionElement->setIndentation($submittedElement->getIndentation());
1254 }
1255
1256 $solutionOrderingElementList->addElement($solutionElement);
1257 }
1258
1259 return $solutionOrderingElementList;
1260 }
1261
1265 private $postSolutionOrderingElementList = null;
1266
1268 {
1269 if ($this->postSolutionOrderingElementList === null) {
1270 $post_array = $_POST;
1271 if (!is_array($post_array)) {
1272 global $DIC;
1273 $request = $DIC->http()->request();
1274 $post_array = $request->getParsedBody();
1275 }
1276 $list = $this->fetchSolutionListFromFormSubmissionData($post_array);
1277 $this->postSolutionOrderingElementList = $list;
1278 }
1279
1280 return $this->postSolutionOrderingElementList;
1281 }
1282
1283 public function getSolutionPostSubmit(): array
1284 {
1285 return $this->fetchSolutionSubmit($_POST);
1286 }
1287
1288 protected function calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList): float
1289 {
1290 $reachedPoints = $this->getPoints();
1291
1292 foreach ($this->getOrderingElementList() as $correctElement) {
1293 $userElement = $solutionOrderingElementList->getElementByPosition($correctElement->getPosition());
1294
1295 if (!$correctElement->isSameElement($userElement)) {
1296 $reachedPoints = 0;
1297 break;
1298 }
1299 }
1300
1301 return $reachedPoints;
1302 }
1303
1309 public function getOperators($expression): array
1310 {
1312 }
1313
1314 public function getExpressionTypes(): array
1315 {
1316 return array(
1321 );
1322 }
1323
1330 public function getUserQuestionResult($active_id, $pass): ilUserQuestionResult
1331 {
1333 global $DIC;
1334 $ilDB = $DIC['ilDB'];
1335 $result = new ilUserQuestionResult($this, $active_id, $pass);
1336
1337 $maxStep = $this->lookupMaxStep($active_id, $pass);
1338
1339 if ($maxStep !== null) {
1340 $data = $ilDB->queryF(
1341 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY value1 ASC ",
1342 array("integer", "integer", "integer","integer"),
1343 array($active_id, $pass, $this->getId(), $maxStep)
1344 );
1345 } else {
1346 $data = $ilDB->queryF(
1347 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY value1 ASC ",
1348 array("integer", "integer", "integer"),
1349 array($active_id, $pass, $this->getId())
1350 );
1351 }
1352
1353 $elements = array();
1354 while ($row = $ilDB->fetchAssoc($data)) {
1355 $newKey = explode(":", $row["value2"]);
1356
1357 foreach ($this->getOrderingElementList() as $answer) {
1358 // Images nut supported
1359 if (!$this->isOrderingTypeNested()) {
1360 if ($answer->getSolutionIdentifier() == $row["value1"]) {
1361 $elements[$row["value2"]] = $answer->getSolutionIdentifier() + 1;
1362 break;
1363 }
1364 } else {
1365 if ($answer->getRandomIdentifier() == $newKey[0]) {
1366 $elements[$row["value1"]] = $answer->getSolutionIdentifier() + 1;
1367 break;
1368 }
1369 }
1370 }
1371 }
1372
1373 ksort($elements);
1374
1375 foreach (array_values($elements) as $element) {
1376 $result->addKeyValue($element, $element);
1377 }
1378
1379 $points = $this->calculateReachedPoints($active_id, $pass);
1380 $max_points = $this->getMaximumPoints();
1381
1382 $result->setReachedPercentage(($points / $max_points) * 100);
1383
1384 return $result;
1385 }
1386
1394 public function getAvailableAnswerOptions($index = null)
1395 {
1396 if ($index !== null) {
1397 return $this->getOrderingElementList()->getElementByPosition($index);
1398 }
1399
1400 return $this->getOrderingElementList()->getElements();
1401 }
1402
1406 protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId): void
1407 {
1408 parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1409 $this->duplicateImages($dupQuestionId, $dupParentObjId, $origQuestionId, $origParentObjId);
1410 }
1411
1413 {
1414 return parent::buildTestPresentationConfig()
1416 ->setUseUnchangedAnswerLabel($this->lng->txt('tst_unchanged_order_is_correct'));
1417 }
1418
1419 protected function ensureImagePathExists(): void
1420 {
1421 if (!file_exists($this->getImagePath())) {
1422 ilFileUtils::makeDirParents($this->getImagePath());
1423 }
1424 }
1425
1426 public function fetchSolutionSubmit($formSubmissionDataStructure): array
1427 {
1428 $solutionSubmit = array();
1429
1430 if (isset($formSubmissionDataStructure['orderresult'])) {
1431 $orderresult = $formSubmissionDataStructure['orderresult'];
1432
1433 if (strlen($orderresult)) {
1434 $orderarray = explode(":", $orderresult);
1435 $ordervalue = 1;
1436 foreach ($orderarray as $index) {
1437 $idmatch = null;
1438 if (preg_match("/id_(\\d+)/", $index, $idmatch)) {
1439 $randomid = $idmatch[1];
1440 foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1441 if ($answer->getRandomIdentifier() == $randomid) {
1442 $solutionSubmit[$answeridx] = $ordervalue;
1443 $ordervalue++;
1444 }
1445 }
1446 }
1447 }
1448 }
1449 } elseif ($this->getOrderingType() == OQ_NESTED_TERMS || $this->getOrderingType() == OQ_NESTED_PICTURES) {
1450 $index = 0;
1451 foreach ($formSubmissionDataStructure['content'] as $randomId => $content) {
1452 $indentation = $formSubmissionDataStructure['indentation'];
1453
1454 $value1 = $index++;
1455 $value2 = implode(':', array($randomId, $indentation));
1456
1457 $solutionSubmit[$value1] = $value2;
1458 }
1459 } else {
1460 foreach ($formSubmissionDataStructure as $key => $value) {
1461 $matches = null;
1462 if (preg_match("/^order_(\d+)/", $key, $matches)) {
1463 if (!(preg_match("/initial_value_\d+/", $value))) {
1464 if (strlen($value)) {
1465 foreach ($this->getOrderingElementList() as $answeridx => $answer) {
1466 if ($answer->getRandomIdentifier() == $matches[1]) {
1467 $solutionSubmit[$answeridx] = $value;
1468 }
1469 }
1470 }
1471 }
1472 }
1473 }
1474 }
1475
1476 return $solutionSubmit;
1477 }
1478
1480 {
1481 require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssOrderingFormValuesObjectsConverter.php';
1482 $converter = new ilAssOrderingFormValuesObjectsConverter();
1483 $converter->setPostVar(self::ORDERING_ELEMENT_FORM_FIELD_POSTVAR);
1484
1485 return $converter;
1486 }
1487
1489 {
1490 $formDataConverter = $this->buildOrderingElementFormDataConverter();
1492
1493 $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1494 $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1495 $formDataConverter->setImageFsPath($this->getImagePath());
1496
1497 if ($this->getThumbPrefix()) {
1498 $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1499 }
1500 return $formDataConverter;
1501 }
1502
1504 {
1505 $formDataConverter = $this->buildOrderingElementFormDataConverter();
1507 return $formDataConverter;
1508 }
1509
1511 {
1512 $formDataConverter = $this->buildOrderingElementFormDataConverter();
1514
1515 if ($this->getOrderingType() == OQ_NESTED_PICTURES) {
1516 $formDataConverter->setImageRemovalCommand(self::ORDERING_ELEMENT_FORM_CMD_REMOVE_IMG);
1517 $formDataConverter->setImageUrlPath($this->getImagePathWeb());
1518 $formDataConverter->setThumbnailPrefix($this->getThumbPrefix());
1519 }
1520
1521 return $formDataConverter;
1522 }
1523}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$filename
Definition: buildRTE.php:78
repository for assOrderingQuestion (the answer elements within, at least...)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getOrderElements()
Returns the answers array.
getOperators($expression)
Get all available operations for a specific question.
getSolutionValuePairBrandedOrderingElementBySolutionIdentifier($value1, $value2)
getAnswer($index=0)
Returns the ordering element from the given position.
getExpressionTypes()
Get all available expression types for a specific question.
duplicate(bool $for_test=true, ?string $title="", ?string $author="", ?string $owner="", $testObjId=null)
getQuestionType()
Returns the question type of the question.
copyImages($question_id, $source_questionpool)
initOrderingElementAuthoringProperties(ilFormPropertyGUI $formField)
getAnswerTableName()
Returns the name of the answer table in the database.
getSolutionOrderingElementList($indexedSolutionValues)
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
toJSON()
Returns a JSON representation of the question.
setOrderingType($ordering_type=self::OQ_TERMS)
fetchSolutionListFromFormSubmissionData($userSolutionPost)
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
isImageReplaced(ilAssOrderingElement $newElement, ilAssOrderingElement $oldElement)
isComplete()
Returns true, if a ordering question is complete for use.
saveToDb($original_id="")
Saves a assOrderingQuestion object to a database.
buildTestPresentationConfig()
build basic test question configuration instance
getOrderingElementListForSolutionOutput($forceCorrectSolution, $activeId, $passIndex)
fetchSolutionSubmit($formSubmissionDataStructure)
savePreviewData(ilAssQuestionPreviewSession $previewSession)
storeImageFile(string $upload_file, string $upload_name)
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $ordering_type=self::OQ_TERMS)
assOrderingQuestion constructor
initOrderingElementFormFieldLabels(ilFormPropertyGUI $formField)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getSolutionValuePairBrandedOrderingElementByRandomIdentifier($value1, $value2)
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
loadFromDb($question_id)
Loads a assOrderingQuestion object from a database.
setOrderingElementList(ilAssOrderingElementList $list)
duplicateImages($src_question_id, $src_object_id, $dest_question_id, $dest_object_id)
getSolutionOrderingElementListForTestOutput(ilAssNestedOrderingElementsInputGUI $inputGUI, $lastPost, $activeId, $pass)
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
{}
deleteAnswer($randomIdentifier)
Deletes an answer with a given index.
calculateReachedPointsForSolution(ilAssOrderingElementList $solutionOrderingElementList)
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
setExportDetailsXLS(ilAssExcelFormatHelper $worksheet, int $startrow, int $active_id, int $pass)
{}
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
copyObject($target_questionpool_id, $title="")
Copies an assOrderingQuestion object.
updateImageFile(string $existing_image_name)
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
Abstract basic class which is to be extended by the concrete assessment question type classes.
setOriginalId(?int $original_id)
string $question
The question text.
setId(int $id=-1)
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
setQuestion(string $question="")
static _getOriginalId(int $question_id)
saveQuestionDataToDb(int $original_id=-1)
setAuthor(string $author="")
setThumbSize(int $a_size)
setComment(string $comment="")
setObjId(int $obj_id=0)
setOwner(int $owner=-1)
setNrOfTries(int $a_nr_of_tries)
setLifecycle(ilAssQuestionLifecycle $lifecycle)
setTitle(string $title="")
setPoints(float $points)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setCell($a_row, $a_col, $a_value, $datatype=null)
static buildInstance(int $question_id, array $elements=[])
ensureValidIdentifiers(ilAssOrderingElement $element)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setBold(string $a_coords)
Set cell(s) to bold.
getColumnCoord(int $a_col)
Get column "name" from number.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
static rename(string $a_source, string $a_target)
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
This class represents a property in a property form.
static _getMobsOfObject(string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static convertImage(string $a_from, string $a_to, string $a_target_format="", string $a_geometry="", string $a_background_color="")
convert image
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setIsUnchangedAnswerPossible($isUnchangedAnswerPossible)
Set if the saving of an unchanged answer is supported with an additional checkbox.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
global $DIC
Definition: feed.php:28
$mobs
Definition: imgupload.php:70
const OQ_NESTED_PICTURES
const OQ_TERMS
const OQ_NESTED_TERMS
const OQ_PICTURES
Ordering question constants.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
$path
Definition: ltiservices.php:32
$index
Definition: metadata.php:145
$i
Definition: metadata.php:41
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
Class ChatMainBarProvider \MainMenu\Provider.
$post_array
Definition: webdav.php:31