ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.assMatchingQuestion.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7require_once './Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
10
25{
43
49 protected $terms;
50
51 protected $definitions;
57 var $thumb_geometry = 100;
58
65
66 const MATCHING_MODE_1_ON_1 = '1:1';
67 const MATCHING_MODE_N_ON_N = 'n:n';
68
70
85 public function __construct(
86 $title = "",
87 $comment = "",
88 $author = "",
89 $owner = -1,
90 $question = "",
92 )
93 {
94 parent::__construct($title, $comment, $author, $owner, $question);
95 $this->matchingpairs = array();
96 $this->matching_type = $matching_type;
97 $this->terms = array();
98 $this->definitions = array();
99 }
100
106 public function isComplete()
107 {
108 if (strlen($this->title)
109 && $this->author
110 && $this->question
111 && count($this->matchingpairs)
112 && $this->getMaximumPoints() > 0
113 )
114 {
115 return true;
116 }
117 return false;
118 }
119
126 public function saveToDb($original_id = "")
127 {
128 global $ilDB;
129
132 $this->saveAnswerSpecificDataToDb( $ilDB );
133
134
135 parent::saveToDb($original_id);
136 }
137
139 {
140 global $ilDB;
141 // delete old terms
142 $ilDB->manipulateF( "DELETE FROM qpl_a_mterm WHERE question_fi = %s",
143 array( 'integer' ),
144 array( $this->getId() )
145 );
146
147 // delete old definitions
148 $ilDB->manipulateF( "DELETE FROM qpl_a_mdef WHERE question_fi = %s",
149 array( 'integer' ),
150 array( $this->getId() )
151 );
152
153 $termids = array();
154 // write terms
155 foreach ($this->terms as $key => $term)
156 {
157 $next_id = $ilDB->nextId( 'qpl_a_mterm' );
158 $ilDB->insert('qpl_a_mterm', array(
159 'term_id' => array('integer', $next_id),
160 'question_fi' => array('integer', $this->getId()),
161 'picture' => array('text', $term->picture),
162 'term' => array('text', $term->text),
163 'ident' => array('integer', $term->identifier)
164 ));
165 $termids[$term->identifier] = $next_id;
166 }
167
168 $definitionids = array();
169 // write definitions
170 foreach ($this->definitions as $key => $definition)
171 {
172 $next_id = $ilDB->nextId( 'qpl_a_mdef' );
173 $ilDB->insert('qpl_a_mdef', array(
174 'def_id' => array('integer', $next_id),
175 'question_fi' => array('integer', $this->getId()),
176 'picture' => array('text', $definition->picture),
177 'definition' => array('text', $definition->text),
178 'ident' => array('integer', $definition->identifier)
179 ));
180 $definitionids[$definition->identifier] = $next_id;
181 }
182
183 $ilDB->manipulateF( "DELETE FROM qpl_a_matching WHERE question_fi = %s",
184 array( 'integer' ),
185 array( $this->getId() )
186 );
187 $matchingpairs = $this->getMatchingPairs();
188 foreach ($matchingpairs as $key => $pair)
189 {
190 $next_id = $ilDB->nextId( 'qpl_a_matching' );
191 $ilDB->manipulateF( "INSERT INTO qpl_a_matching (answer_id, question_fi, points, term_fi, definition_fi) VALUES (%s, %s, %s, %s, %s)",
192 array( 'integer', 'integer', 'float', 'integer', 'integer' ),
193 array(
194 $next_id,
195 $this->getId(),
196 $pair->points,
197 $termids[$pair->term->identifier],
198 $definitionids[$pair->definition->identifier]
199 )
200 );
201 }
202
203 $this->rebuildThumbnails();
204 }
205
207 {
208 global $ilDB;
209
210 // save additional data
211
212 $ilDB->manipulateF(
213 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
214 array( "integer" ), array( $this->getId() )
215 );
216
217 $ilDB->insert($this->getAdditionalTableName(), array(
218 'question_fi' => array('integer', $this->getId()),
219 'shuffle' => array('text', $this->shuffle),
220 'matching_type' => array('text', $this->matching_type),
221 'thumb_geometry' => array('integer', $this->getThumbGeometry()),
222 'matching_mode' => array('text', $this->getMatchingMode())
223 ));
224 }
225
232 public function loadFromDb($question_id)
233 {
234 global $ilDB;
235
236 $query = "
237 SELECT qpl_questions.*,
238 {$this->getAdditionalTableName()}.*
239 FROM qpl_questions
240 LEFT JOIN {$this->getAdditionalTableName()}
241 ON {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id
242 WHERE qpl_questions.question_id = %s
243 ";
244
245 $result = $ilDB->queryF(
246 $query, array('integer'), array($question_id)
247 );
248
249 if ($result->numRows() == 1)
250 {
251 $data = $ilDB->fetchAssoc($result);
252 $this->setId($question_id);
253 $this->setObjId($data["obj_fi"]);
254 $this->setTitle($data["title"]);
255 $this->setComment($data["description"]);
256 $this->setOriginalId($data["original_id"]);
257 $this->setNrOfTries($data['nr_of_tries']);
258 $this->setAuthor($data["author"]);
259 $this->setPoints($data["points"]);
260 $this->setOwner($data["owner"]);
261 include_once("./Services/RTE/classes/class.ilRTE.php");
262 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
263 $this->setThumbGeometry($data["thumb_geometry"]);
264 $this->setShuffle($data["shuffle"]);
265 $this->setMatchingMode($data['matching_mode'] === null ? self::MATCHING_MODE_1_ON_1 : $data['matching_mode']);
266 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
267
268 try
269 {
270 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
271 }
273 {
274 }
275 }
276
277 $termids = array();
278 $result = $ilDB->queryF("SELECT * FROM qpl_a_mterm WHERE question_fi = %s ORDER BY term_id ASC",
279 array('integer'),
280 array($question_id)
281 );
282 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
283 $this->terms = array();
284 if ($result->numRows() > 0)
285 {
286 while ($data = $ilDB->fetchAssoc($result))
287 {
288 $term = new assAnswerMatchingTerm($data['term'], $data['picture'], $data['ident']);
289 array_push($this->terms, $term);
290 $termids[$data['term_id']] = $term;
291 }
292 }
293
294 $definitionids = array();
295 $result = $ilDB->queryF("SELECT * FROM qpl_a_mdef WHERE question_fi = %s ORDER BY def_id ASC",
296 array('integer'),
297 array($question_id)
298 );
299 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
300 $this->definitions = array();
301 if ($result->numRows() > 0)
302 {
303 while ($data = $ilDB->fetchAssoc($result))
304 {
305 $definition = new assAnswerMatchingDefinition($data['definition'], $data['picture'], $data['ident']);
306 array_push($this->definitions, $definition);
307 $definitionids[$data['def_id']] = $definition;
308 }
309 }
310
311 $this->matchingpairs = array();
312 $result = $ilDB->queryF("SELECT * FROM qpl_a_matching WHERE question_fi = %s ORDER BY answer_id",
313 array('integer'),
314 array($question_id)
315 );
316 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php";
317 if ($result->numRows() > 0)
318 {
319 while ($data = $ilDB->fetchAssoc($result))
320 {
321 array_push($this->matchingpairs, new assAnswerMatchingPair($termids[$data['term_fi']], $definitionids[$data['definition_fi']], $data['points']));
322 }
323 }
324 parent::loadFromDb($question_id);
325 }
326
327
331 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
332 {
333 if ($this->id <= 0)
334 {
335 // The question has not been saved. It cannot be duplicated
336 return;
337 }
338 // duplicate the question in database
339 $this_id = $this->getId();
340 $thisObjId = $this->getObjId();
341
342 $clone = $this;
343 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
345 $clone->id = -1;
346
347 if( (int)$testObjId > 0 )
348 {
349 $clone->setObjId($testObjId);
350 }
351
352 if ($title)
353 {
354 $clone->setTitle($title);
355 }
356 if ($author)
357 {
358 $clone->setAuthor($author);
359 }
360 if ($owner)
361 {
362 $clone->setOwner($owner);
363 }
364 if ($for_test)
365 {
366 $clone->saveToDb($original_id);
367 }
368 else
369 {
370 $clone->saveToDb();
371 }
372
373 // copy question page content
374 $clone->copyPageOfQuestion($this_id);
375 // copy XHTML media objects
376 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
377 // duplicate the image
378 $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
379
380 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
381
382 return $clone->id;
383 }
384
388 public function copyObject($target_questionpool_id, $title = "")
389 {
390 if ($this->id <= 0)
391 {
392 // The question has not been saved. It cannot be duplicated
393 return;
394 }
395 // duplicate the question in database
396 $clone = $this;
397 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
399 $clone->id = -1;
400 $source_questionpool_id = $this->getObjId();
401 $clone->setObjId($target_questionpool_id);
402 if ($title)
403 {
404 $clone->setTitle($title);
405 }
406 $clone->saveToDb();
407 // copy question page content
408 $clone->copyPageOfQuestion($original_id);
409 // copy XHTML media objects
410 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
411 // duplicate the image
412 $clone->copyImages($original_id, $source_questionpool_id);
413
414 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
415
416 return $clone->id;
417 }
418
419 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
420 {
421 if ($this->id <= 0)
422 {
423 // The question has not been saved. It cannot be duplicated
424 return;
425 }
426
427 include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
428
429 $sourceQuestionId = $this->id;
430 $sourceParentId = $this->getObjId();
431
432 // duplicate the question in database
433 $clone = $this;
434 $clone->id = -1;
435
436 $clone->setObjId($targetParentId);
437
438 if ($targetQuestionTitle)
439 {
440 $clone->setTitle($targetQuestionTitle);
441 }
442
443 $clone->saveToDb();
444 // copy question page content
445 $clone->copyPageOfQuestion($sourceQuestionId);
446 // copy XHTML media objects
447 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
448 // duplicate the image
449 $clone->copyImages($sourceQuestionId, $sourceParentId);
450
451 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
452
453 return $clone->id;
454 }
455
456 public function duplicateImages($question_id, $objectId = null)
457 {
458 global $ilLog;
459 $imagepath = $this->getImagePath();
460 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
461
462 if( (int)$objectId > 0 )
463 {
464 $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
465 }
466
467 foreach ($this->terms as $term)
468 {
469 if (strlen($term->picture))
470 {
471 $filename = $term->picture;
472 if (!file_exists($imagepath))
473 {
474 ilUtil::makeDirParents($imagepath);
475 }
476 if (!@copy($imagepath_original . $filename, $imagepath . $filename))
477 {
478 $ilLog->write("matching question image could not be duplicated: $imagepath_original$filename");
479 }
480 if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename))
481 {
482 if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
483 {
484 $ilLog->write("matching question image thumbnail could not be duplicated: $imagepath_original" . $this->getThumbPrefix() . $filename);
485 }
486 }
487 }
488 }
489 foreach ($this->definitions as $definition)
490 {
491 if (strlen($definition->picture))
492 {
493 $filename = $definition->picture;
494 if (!file_exists($imagepath))
495 {
496 ilUtil::makeDirParents($imagepath);
497 }
498 if (!@copy($imagepath_original . $filename, $imagepath . $filename))
499 {
500 $ilLog->write("matching question image could not be duplicated: $imagepath_original$filename");
501 }
502 if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename))
503 {
504 if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
505 {
506 $ilLog->write("matching question image thumbnail could not be duplicated: $imagepath_original" . $this->getThumbPrefix() . $filename);
507 }
508 }
509 }
510 }
511 }
512
513 public function copyImages($question_id, $source_questionpool)
514 {
515 global $ilLog;
516
517 $imagepath = $this->getImagePath();
518 $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
519 $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
520 foreach ($this->terms as $term)
521 {
522 if (strlen($term->picture))
523 {
524 if (!file_exists($imagepath))
525 {
526 ilUtil::makeDirParents($imagepath);
527 }
528 $filename = $term->picture;
529 if (!@copy($imagepath_original . $filename, $imagepath . $filename))
530 {
531 $ilLog->write("matching question image could not be copied: $imagepath_original$filename");
532 }
533 if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename))
534 {
535 $ilLog->write("matching question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
536 }
537 }
538 }
539 foreach ($this->definitions as $definition)
540 {
541 if (strlen($definition->picture))
542 {
543 $filename = $definition->picture;
544 if (!file_exists($imagepath))
545 {
546 ilUtil::makeDirParents($imagepath);
547 }
548
549 if( assQuestion::isFileAvailable($imagepath_original . $filename) )
550 {
551 copy($imagepath_original . $filename, $imagepath . $filename);
552 }
553 else
554 {
555 $ilLog->write("matching question image could not be copied: $imagepath_original$filename");
556 }
557
558 if( assQuestion::isFileAvailable($imagepath_original . $this->getThumbPrefix() . $filename) )
559 {
560 copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename);
561 }
562 else
563 {
564 $ilLog->write("matching question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
565 }
566 }
567 }
568 }
569
580 public function insertMatchingPair($position, $term = null, $definition = null, $points = 0.0)
581 {
582 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php";
583 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
584 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
585 if (is_null($term)) $term = new assAnswerMatchingTerm();
586 if (is_null($definition)) $definition = new assAnswerMatchingDefinition();
587 $pair = new assAnswerMatchingPair($term, $definition, $points);
588 if ($position < count($this->matchingpairs))
589 {
590 $part1 = array_slice($this->matchingpairs, 0, $position);
591 $part2 = array_slice($this->matchingpairs, $position);
592 $this->matchingpairs = array_merge($part1, array($pair), $part2);
593 }
594 else
595 {
596 array_push($this->matchingpairs, $pair);
597 }
598 }
599
611 public function addMatchingPair($term = null, $definition = null, $points = 0.0)
612 {
613 require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php';
614 require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php';
615 require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php';
616 if (is_null($term))
617 {
618 $term = new assAnswerMatchingTerm();
619 }
620 if (is_null($definition))
621 {
622 $definition = new assAnswerMatchingDefinition();
623 }
624 $pair = new assAnswerMatchingPair($term, $definition, $points);
625 array_push($this->matchingpairs, $pair);
626 }
627
631 public function getTermWithIdentifier($a_identifier)
632 {
633 foreach ($this->terms as $term)
634 {
635 if ($term->identifier == $a_identifier) return $term;
636 }
637 return null;
638 }
639
643 public function getDefinitionWithIdentifier($a_identifier)
644 {
645 foreach ($this->definitions as $definition)
646 {
647 if ($definition->identifier == $a_identifier) return $definition;
648 }
649 return null;
650 }
651
660 public function getMatchingPair($index = 0)
661 {
662 if ($index < 0)
663 {
664 return NULL;
665 }
666 if (count($this->matchingpairs) < 1)
667 {
668 return NULL;
669 }
670 if ($index >= count($this->matchingpairs))
671 {
672 return NULL;
673 }
674 return $this->matchingpairs[$index];
675 }
676
684 public function deleteMatchingPair($index = 0)
685 {
686 if ($index < 0)
687 {
688 return;
689 }
690 if (count($this->matchingpairs) < 1)
691 {
692 return;
693 }
694 if ($index >= count($this->matchingpairs))
695 {
696 return;
697 }
698 unset($this->matchingpairs[$index]);
699 $this->matchingpairs = array_values($this->matchingpairs);
700 }
701
706 public function flushMatchingPairs()
707 {
708 $this->matchingpairs = array();
709 }
710
717 public function getMatchingPairCount()
718 {
719 return count($this->matchingpairs);
720 }
721
728 public function getTerms()
729 {
730 return $this->terms;
731 }
732
739 public function getDefinitions()
740 {
741 return $this->definitions;
742 }
743
750 public function getTermCount()
751 {
752 return count($this->terms);
753 }
754
761 public function getDefinitionCount()
762 {
763 return count($this->definitions);
764 }
765
772 public function addTerm($term)
773 {
774 array_push($this->terms, $term);
775 }
776
783 public function addDefinition($definition)
784 {
785 array_push($this->definitions, $definition);
786 }
787
794 public function insertTerm($position, $term = null)
795 {
796 if (is_null($term))
797 {
798 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
799 $term = new assAnswerMatchingTerm();
800 }
801 if ($position < count($this->terms))
802 {
803 $part1 = array_slice($this->terms, 0, $position);
804 $part2 = array_slice($this->terms, $position);
805 $this->terms = array_merge($part1, array($term), $part2);
806 }
807 else
808 {
809 array_push($this->terms, $term);
810 }
811 }
812
819 public function insertDefinition($position, $definition = null)
820 {
821 if (is_null($definition))
822 {
823 include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
824 $definition = new assAnswerMatchingDefinition();
825 }
826 if ($position < count($this->definitions))
827 {
828 $part1 = array_slice($this->definitions, 0, $position);
829 $part2 = array_slice($this->definitions, $position);
830 $this->definitions = array_merge($part1, array($definition), $part2);
831 }
832 else
833 {
834 array_push($this->definitions, $definition);
835 }
836 }
837
842 public function flushTerms()
843 {
844 $this->terms = array();
845 }
846
851 public function flushDefinitions()
852 {
853 $this->definitions = array();
854 }
855
862 public function deleteTerm($position)
863 {
864 unset($this->terms[$position]);
865 $this->terms = array_values($this->terms);
866 }
867
874 public function deleteDefinition($position)
875 {
876 unset($this->definitions[$position]);
877 $this->definitions = array_values($this->definitions);
878 }
879
887 public function setTerm($term, $index)
888 {
889 $this->terms[$index] = $term;
890 }
891
902 public function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = FALSE)
903 {
904 if( $returndetails )
905 {
906 throw new ilTestException('return details not implemented for '.__METHOD__);
907 }
908
909 global $ilDB;
910
911 $found_values = array();
912 if (is_null($pass))
913 {
914 $pass = $this->getSolutionMaxPass($active_id);
915 }
916 $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
917 while ($data = $ilDB->fetchAssoc($result))
918 {
919 if (strcmp($data["value1"], "") != 0)
920 {
921 if( !isset($found_values[$data['value2']]) )
922 {
923 $found_values[$data['value2']] = array();
924 }
925
926 $found_values[$data['value2']][] = $data['value1'];
927 }
928 }
929
930 $points = $this->calculateReachedPointsForSolution($found_values);
931
932 return $points;
933 }
934
939 {
940 $points = 0;
941
942 foreach( $this->getMaximumScoringMatchingPairs() as $pair )
943 {
944 $points += $pair->points;
945 }
946
947 return $points;
948 }
949
951 {
952 if( $this->getMatchingMode() == self::MATCHING_MODE_N_ON_N )
953 {
954 return $this->getPositiveScoredMatchingPairs();
955 }
956 elseif( $this->getMatchingMode() == self::MATCHING_MODE_1_ON_1 )
957 {
959 }
960
961 return array();
962 }
963
965 {
966 $matchingPairs = array();
967
968 foreach( $this->matchingpairs as $pair )
969 {
970 if( $pair->points <= 0 )
971 {
972 continue;
973 }
974
975 $matchingPairs[] = $pair;
976 }
977
978 return $matchingPairs;
979 }
980
982 {
983 $matchingPairsByDefinition = array();
984
985 foreach( $this->matchingpairs as $pair )
986 {
987 if( $pair->points <= 0 )
988 {
989 continue;
990 }
991
992 $defId = $pair->definition->identifier;
993
994 if( !isset($matchingPairsByDefinition[$defId]) )
995 {
996 $matchingPairsByDefinition[$defId] = $pair;
997 }
998 elseif( $pair->points > $matchingPairsByDefinition[$defId]->points )
999 {
1000 $matchingPairsByDefinition[$defId] = $pair;
1001 }
1002 }
1003
1004 return $matchingPairsByDefinition;
1005 }
1006
1011 public function fetchIndexedValuesFromValuePairs(array $valuePairs)
1012 {
1013 $indexedValues = array();
1014
1015 foreach($valuePairs as $valuePair)
1016 {
1017 if( !isset($indexedValues[$valuePair['value2']]) )
1018 {
1019 $indexedValues[$valuePair['value2']] = array();
1020 }
1021
1022 $indexedValues[$valuePair['value2']][] = $valuePair['value1'];
1023 }
1024
1025 return $indexedValues;
1026 }
1027
1037 {
1038 $extension = "";
1039 if (preg_match("/.*\\.(\\w+)$/", $filename, $matches))
1040 {
1041 $extension = $matches[1];
1042 }
1043 return md5($filename) . "." . $extension;
1044 }
1045
1046 public function removeTermImage($index)
1047 {
1048 $term = $this->terms[$index];
1049 if (is_object($term))
1050 {
1051 $this->deleteImagefile($term->picture);
1052 $term->picture = null;
1053 }
1054 }
1055
1056 public function removeDefinitionImage($index)
1057 {
1058 $definition = $this->definitions[$index];
1059 if (is_object($definition))
1060 {
1061 $this->deleteImagefile($definition->picture);
1062 $definition->picture = null;
1063 }
1064 }
1065
1066
1074 {
1075 $deletename = $filename;
1076 $result = @unlink($this->getImagePath().$deletename);
1077 $result = $result & @unlink($this->getImagePath().$this->getThumbPrefix() . $deletename);
1078 return $result;
1079 }
1080
1089 function setImageFile($image_tempfilename, $image_filename, $previous_filename = '')
1090 {
1091 $result = TRUE;
1092 if (strlen($image_tempfilename))
1093 {
1094 $image_filename = str_replace(" ", "_", $image_filename);
1095 $imagepath = $this->getImagePath();
1096 if (!file_exists($imagepath))
1097 {
1098 ilUtil::makeDirParents($imagepath);
1099 }
1100 $savename = $image_filename;
1101 if (!ilUtil::moveUploadedFile($image_tempfilename, $savename, $imagepath.$savename))
1102 {
1103 $result = FALSE;
1104 }
1105 else
1106 {
1107 // create thumbnail file
1108 $thumbpath = $imagepath . $this->getThumbPrefix() . $savename;
1109 ilUtil::convertImage($imagepath.$savename, $thumbpath, "JPEG", $this->getThumbGeometry());
1110 }
1111 if ($result && (strcmp($image_filename, $previous_filename) != 0) && (strlen($previous_filename)))
1112 {
1113 $this->deleteImagefile($previous_filename);
1114 }
1115 }
1116 return $result;
1117 }
1118
1120 {
1121 $postData = $_POST['matching'][$this->getId()];
1122
1123 $matchings = array();
1124
1125 foreach( $this->getDefinitions() as $definition )
1126 {
1127 if( isset($postData[$definition->identifier]) )
1128 {
1129 foreach( $this->getTerms() as $term )
1130 {
1131 if( isset($postData[$definition->identifier][$term->identifier]) )
1132 {
1133 if( !is_array($postData[$definition->identifier]) )
1134 {
1135 $postData[$definition->identifier] = array();
1136 }
1137
1138 $matchings[$definition->identifier][] = $term->identifier;
1139 }
1140 }
1141 }
1142 }
1143
1144 return $matchings;
1145 }
1146
1147 private function checkSubmittedMatchings($submittedMatchings)
1148 {
1149 if( $this->getMatchingMode() == self::MATCHING_MODE_N_ON_N )
1150 {
1151 return true;
1152 }
1153
1154 $handledTerms = array();
1155
1156 foreach( $submittedMatchings as $definition => $terms )
1157 {
1158 if( count($terms) > 1 )
1159 {
1160 ilUtil::sendFailure($this->lng->txt("multiple_matching_values_selected"), true);
1161 return false;
1162 }
1163
1164 foreach( $terms as $i => $term )
1165 {
1166 if( isset($handledTerms[$term]) )
1167 {
1168 ilUtil::sendFailure($this->lng->txt("duplicate_matching_values_selected"), true);
1169 return false;
1170 }
1171
1172 $handledTerms[$term] = $term;
1173 }
1174 }
1175
1176 return true;
1177 }
1178
1187 public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
1188 {
1189 global $ilDB;
1190
1191 $submittedMatchings = $this->fetchSubmittedMatchingsFromPost();
1192 $submittedMatchingsValid = $this->checkSubmittedMatchings($submittedMatchings);
1193
1194 $matchingsExist = false;
1195
1196 if ($submittedMatchingsValid)
1197 {
1198 if (is_null($pass))
1199 {
1200 include_once "./Modules/Test/classes/class.ilObjTest.php";
1201 $pass = ilObjTest::_getPass($active_id);
1202 }
1203
1204 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function() use (&$matchingsExist, $submittedMatchings, $active_id, $pass, $authorized) {
1205
1206 $this->removeCurrentSolution($active_id, $pass, $authorized);
1207
1208 foreach($submittedMatchings as $definition => $terms)
1209 {
1210 foreach($terms as $i => $term)
1211 {
1212 $this->saveCurrentSolution($active_id, $pass, $term, $definition, $authorized);
1213 $matchingsExist = true;
1214 }
1215 }
1216
1217 });
1218
1219 $saveWorkingDataResult = true;
1220 }
1221 else
1222 {
1223 $saveWorkingDataResult = false;
1224 }
1225
1226 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1228 {
1229 if( $matchingsExist )
1230 {
1231 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1232 }
1233 else
1234 {
1235 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1236 }
1237 }
1238
1239 return $saveWorkingDataResult;
1240 }
1241
1242 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1243 {
1244 $submittedMatchings = $this->fetchSubmittedMatchingsFromPost();
1245
1246 if( $this->checkSubmittedMatchings($submittedMatchings) )
1247 {
1248 $previewSession->setParticipantsSolution($submittedMatchings);
1249 }
1250 }
1251
1255 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
1256 {
1257 // nothing to rework!
1258 }
1259
1260 public function getRandomId()
1261 {
1262 mt_srand((double)microtime()*1000000);
1263 $random_number = mt_rand(1, 100000);
1264 $found = FALSE;
1265 while ($found)
1266 {
1267 $found = FALSE;
1268 foreach ($this->matchingpairs as $key => $pair)
1269 {
1270 if (($pair->term->identifier == $random_number) || ($pair->definition->identifier == $random_number))
1271 {
1272 $found = TRUE;
1273 $random_number++;
1274 }
1275 }
1276 }
1277 return $random_number;
1278 }
1279
1286 public function setShuffle($shuffle = true)
1287 {
1288 switch ($shuffle)
1289 {
1290 case 0:
1291 case 1:
1292 case 2:
1293 case 3:
1294 $this->shuffle = $shuffle;
1295 break;
1296 default:
1297 $this->shuffle = 1;
1298 break;
1299 }
1300 }
1301
1307 public function getQuestionType()
1308 {
1309 return "assMatchingQuestion";
1310 }
1311
1317 public function getAdditionalTableName()
1318 {
1319 return "qpl_qst_matching";
1320 }
1321
1327 public function getAnswerTableName()
1328 {
1329 return array("qpl_a_matching", "qpl_a_mterm");
1330 }
1331
1337 {
1338 return parent::getRTETextWithMediaObjects();
1339 }
1340
1344 public function &getMatchingPairs()
1345 {
1346 return $this->matchingpairs;
1347 }
1348
1352 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1353 {
1354 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1355
1356 $solutions = $this->getSolutionValues($active_id, $pass);
1357
1358 $imagepath = $this->getImagePath();
1359 $i = 1;
1360 foreach ($solutions as $solution)
1361 {
1362 $matches_written = FALSE;
1363 foreach ($this->getMatchingPairs() as $idx => $pair)
1364 {
1365 if (!$matches_written) $worksheet->setCell($startrow + $i, 1, $this->lng->txt("matches"));
1366 $matches_written = TRUE;
1367 if ($pair->definition->identifier == $solution["value2"])
1368 {
1369 if (strlen($pair->definition->text))
1370 {
1371 $worksheet->setCell($startrow + $i, 0, $pair->definition->text);
1372 }
1373 else
1374 {
1375 $worksheet->setCell($startrow + $i, 0, $pair->definition->picture);
1376 }
1377 }
1378 if ($pair->term->identifier == $solution["value1"])
1379 {
1380 if (strlen($pair->term->text))
1381 {
1382 $worksheet->setCell($startrow + $i, 2, $pair->term->text);
1383 }
1384 else
1385 {
1386 $worksheet->setCell($startrow + $i, 2, $pair->term->picture);
1387 }
1388 }
1389 }
1390 $i++;
1391 }
1392
1393 return $startrow + $i + 1;
1394 }
1395
1401 public function getThumbGeometry()
1402 {
1403 return $this->thumb_geometry;
1404 }
1405
1411 public function getThumbSize()
1412 {
1413 return $this->getThumbGeometry();
1414 }
1415
1421 public function setThumbGeometry($a_geometry)
1422 {
1423 $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1424 }
1425
1429 public function rebuildThumbnails()
1430 {
1431 foreach ($this->terms as $term)
1432 {
1433 if (strlen($term->picture)) $this->generateThumbForFile($this->getImagePath(), $term->picture);
1434 }
1435 foreach ($this->definitions as $definition)
1436 {
1437 if (strlen($definition->picture)) $this->generateThumbForFile($this->getImagePath(), $definition->picture);
1438 }
1439 }
1440
1441 public function getThumbPrefix()
1442 {
1443 return "thumb.";
1444 }
1445
1446 protected function generateThumbForFile($path, $file)
1447 {
1448 $filename = $path . $file;
1449 if (@file_exists($filename))
1450 {
1451 $thumbpath = $path . $this->getThumbPrefix() . $file;
1452 $path_info = @pathinfo($filename);
1453 $ext = "";
1454 switch (strtoupper($path_info['extension']))
1455 {
1456 case 'PNG':
1457 $ext = 'PNG';
1458 break;
1459 case 'GIF':
1460 $ext = 'GIF';
1461 break;
1462 default:
1463 $ext = 'JPEG';
1464 break;
1465 }
1466 ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1467 }
1468 }
1469
1474 public function toJSON()
1475 {
1476 $result = array();
1477
1478 $result['id'] = (int) $this->getId();
1479 $result['type'] = (string) $this->getQuestionType();
1480 $result['title'] = (string) $this->getTitle();
1481 $result['question'] = $this->formatSAQuestion($this->getQuestion());
1482 $result['nr_of_tries'] = (int) $this->getNrOfTries();
1483 $result['matching_mode'] = $this->getMatchingMode();
1484 $result['shuffle'] = true;
1485 $result['feedback'] = array(
1486 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1487 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1488 );
1489
1490 require_once 'Services/Randomization/classes/class.ilArrayElementShuffler.php';
1491 $this->setShuffler(new ilArrayElementShuffler());
1492 $seed = $this->getShuffler()->getSeed();
1493
1494 $terms = array();
1495 $this->getShuffler()->setSeed($this->getShuffler()->buildSeedFromString($seed.'terms'));
1496 foreach ($this->getShuffler()->shuffle($this->getTerms()) as $term)
1497 {
1498 $terms[] = array(
1499 "text" => $this->formatSAQuestion($term->text),
1500 "id" =>(int)$this->getId().$term->identifier
1501 );
1502 }
1503 $result['terms'] = $terms;
1504
1505 // alex 9.9.2010 as a fix for bug 6513 I added the question id
1506 // to the "def_id" in the array. The $pair->definition->identifier is not
1507 // unique, since it gets it value from the morder table field
1508 // this value is not changed, when a question is copied.
1509 // thus copying the same question on a page results in problems
1510 // when the second one (the copy) is answered.
1511
1512 $definitions = array();
1513 $this->getShuffler()->setSeed($this->getShuffler()->buildSeedFromString($seed.'definitions'));
1514 foreach ($this->getShuffler()->shuffle($this->getDefinitions()) as $def)
1515 {
1516 $definitions[] = array(
1517 "text" => $this->formatSAQuestion((string) $def->text),
1518 "id" => (int) $this->getId().$def->identifier
1519 );
1520 }
1521 $result['definitions'] = $definitions;
1522
1523 // #10353
1524 $matchings = array();
1525 foreach ($this->getMatchingPairs() as $pair)
1526 {
1527// fau: fixLmMatchingPoints - ignore matching pairs with 0 or negative points
1528 if ($pair->points <= 0)
1529 {
1530 continue;
1531 }
1532// fau.
1533
1534 $pid = $pair->definition->identifier;
1535 if( $this->getMatchingMode() == self::MATCHING_MODE_N_ON_N )
1536 {
1537 $pid .= '::'.$pair->term->identifier;
1538 }
1539
1540 if( !isset($matchings[$pid]) || $matchings[$pid]["points"] < $pair->points )
1541 {
1542 $matchings[$pid] = array(
1543 "term_id" => (int) $this->getId().$pair->term->identifier,
1544 "def_id" => (int) $this->getId().$pair->definition->identifier,
1545 "points" => (int) $pair->points
1546 );
1547 }
1548 }
1549
1550 $result['matchingPairs'] = array_values($matchings);
1551
1552 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1553 $result['mobs'] = $mobs;
1554
1555 global $lng;
1556 $lng->loadLanguageModule('assessment');
1557 $result['reset_button_label'] = $lng->txt("reset_terms");
1558
1559 return json_encode($result);
1560 }
1561
1563 {
1564 return true;
1565 }
1566
1567 public function supportsNonJsOutput()
1568 {
1569 return false;
1570 }
1571
1573 {
1574 $this->matchingMode = $matchingMode;
1575 }
1576
1577 public function getMatchingMode()
1578 {
1579 return $this->matchingMode;
1580 }
1581
1586 protected function calculateReachedPointsForSolution($found_values)
1587 {
1588 $points = 0;
1589 foreach($found_values as $definition => $terms)
1590 {
1591 foreach($terms as $term)
1592 {
1593 foreach($this->matchingpairs as $pair)
1594 {
1595 if($pair->definition->identifier == $definition && $pair->term->identifier == $term)
1596 {
1597 $points += $pair->points;
1598 }
1599 }
1600 }
1601 }
1602 return $points;
1603 }
1604
1613 public function getOperators($expression)
1614 {
1615 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1617 }
1618
1623 public function getExpressionTypes()
1624 {
1625 return array(
1630 );
1631 }
1640 public function getUserQuestionResult($active_id, $pass)
1641 {
1643 global $ilDB;
1644 $result = new ilUserQuestionResult($this, $active_id, $pass);
1645
1646 $data = $ilDB->queryF(
1647 "SELECT ident FROM qpl_a_mdef WHERE question_fi = %s ORDER BY def_id",
1648 array("integer"),
1649 array($this->getId())
1650 );
1651
1652 $definitions = array();
1653 for($index=1; $index <= $ilDB->numRows($data); ++$index)
1654 {
1655 $row = $ilDB->fetchAssoc($data);
1656 $definitions[$row["ident"]] = $index;
1657 }
1658
1659 $data = $ilDB->queryF(
1660 "SELECT ident FROM qpl_a_mterm WHERE question_fi = %s ORDER BY term_id",
1661 array("integer"),
1662 array($this->getId())
1663 );
1664
1665 $terms = array();
1666 for($index=1; $index <= $ilDB->numRows($data); ++$index)
1667 {
1668 $row = $ilDB->fetchAssoc($data);
1669 $terms[$row["ident"]] = $index;
1670 }
1671
1672 $maxStep = $this->lookupMaxStep($active_id, $pass);
1673
1674 if( $maxStep !== null )
1675 {
1676 $data = $ilDB->queryF(
1677 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1678 array("integer", "integer", "integer","integer"),
1679 array($active_id, $pass, $this->getId(), $maxStep)
1680 );
1681 }
1682 else
1683 {
1684 $data = $ilDB->queryF(
1685 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1686 array("integer", "integer", "integer"),
1687 array($active_id, $pass, $this->getId())
1688 );
1689 }
1690
1691 while($row = $ilDB->fetchAssoc($data))
1692 {
1693 if($row["value1"] > 0)
1694 {
1695 $result->addKeyValue($definitions[$row["value2"]],$terms[$row["value1"]]);
1696 }
1697 }
1698
1699 $points = $this->calculateReachedPoints($active_id, $pass);
1700 $max_points = $this->getMaximumPoints();
1701
1702 $result->setReachedPercentage(($points/$max_points) * 100);
1703
1704 return $result;
1705 }
1706
1715 public function getAvailableAnswerOptions($index = null)
1716 {
1717 if($index !== null)
1718 {
1719 return $this->getMatchingPair($index);
1720 }
1721 else
1722 {
1723 return $this->getMatchingPairs();
1724 }
1725 }
1726
1730 protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1731 {
1732 parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1733
1734 $origImagePath = $this->buildImagePath($origQuestionId, $origParentObjId);
1735 $dupImagePath = $this->buildImagePath($dupQuestionId, $dupParentObjId);
1736
1737 ilUtil::delDir($origImagePath);
1738 if(is_dir($dupImagePath))
1739 {
1740 ilUtil::makeDirParents($origImagePath);
1741 ilUtil::rCopy($dupImagePath, $origImagePath);
1742 }
1743 }
1744}
$worksheet
$result
$path
Definition: aliased.php:25
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Class for matching question definitions.
Class for matching question pairs.
Class for matching question terms.
Class for matching questions.
supportsJavascriptOutput()
Returns true if the question type supports JavaScript output.
setThumbGeometry($a_geometry)
Set the thumbnail geometry.
deleteDefinition($position)
Deletes a definition.
getEncryptedFilename($filename)
Returns the encrypted save filename of a matching picture Images are saved with an encrypted filename...
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{Reworks the allready saved working data if neccessary.}
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $matching_type=MT_TERMS_DEFINITIONS)
assMatchingQuestion constructor
getMatchingPairCount()
Returns the number of matching pairs.
calculateReachedPointsForSolution($found_values)
addDefinition($definition)
Adds a definition.
getMaximumPoints()
Calculates and Returns the maximum points, a learner can reach answering the question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
copyObject($target_questionpool_id, $title="")
Copies an assMatchingQuestion.
toJSON()
Returns a JSON representation of the question TODO.
getOperators($expression)
Get all available operations for a specific question.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
getDefinitionCount()
Returns the number of definitions.
getDefinitions()
Returns the definitions of the matching question.
getMatchingPair($index=0)
Returns a matching pair with a given index.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assMatchingQuestion.
getQuestionType()
Returns the question type of the question.
isComplete()
Returns true, if a matching question is complete for use.
insertDefinition($position, $definition=null)
Inserts a definition.
& getMatchingPairs()
Returns the matchingpairs array.
rebuildThumbnails()
Rebuild the thumbnail images with a new thumbnail size.
duplicateImages($question_id, $objectId=null)
getTermCount()
Returns the number of terms.
getThumbGeometry()
Get the thumbnail geometry.
deleteTerm($position)
Deletes a term.
checkSubmittedMatchings($submittedMatchings)
getTerms()
Returns the terms of the matching question.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
addMatchingPair($term=null, $definition=null, $points=0.0)
Adds an matching pair for an matching choice question.
flushDefinitions()
Deletes all definitions.
fetchIndexedValuesFromValuePairs(array $valuePairs)
loadFromDb($question_id)
Loads a assMatchingQuestion object from a database.
getAnswerTableName()
Returns the name of the answer table in the database.
getDefinitionWithIdentifier($a_identifier)
Returns a definition with a given identifier.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
flushTerms()
Deletes all terms.
copyImages($question_id, $source_questionpool)
flushMatchingPairs()
Deletes all matching pairs.
saveToDb($original_id="")
Saves a assMatchingQuestion object to a database.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
setImageFile($image_tempfilename, $image_filename, $previous_filename='')
Sets the image file and uploads the image to the object's image directory.
setShuffle($shuffle=true)
Sets the shuffle flag.
getThumbSize()
Get the thumbnail geometry.
getTermWithIdentifier($a_identifier)
Returns a term with a given identifier.
setTerm($term, $index)
Sets a specific term.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
{}
getExpressionTypes()
Get all available expression types for a specific question.
deleteImagefile($filename)
Deletes an imagefile from the system if the file is deleted manually.
deleteMatchingPair($index=0)
Deletes a matching pair with a given index.
insertMatchingPair($position, $term=null, $definition=null, $points=0.0)
Inserts a matching pair for an matching choice question.
insertTerm($position, $term=null)
Inserts a term.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
setId($id=-1)
Sets the id of the assQuestion object.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
buildImagePath($questionId, $parentObjectId)
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
removeCurrentSolution($active_id, $pass, $authorized=true)
setAuthor($author="")
Sets the authors name of the assQuestion object.
static isFileAvailable($file)
setShuffler(ilArrayElementShuffler $shuffler)
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
setNrOfTries($a_nr_of_tries)
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
setQuestion($question="")
Sets the question string of the question object.
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
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...
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static convertImage($a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
static makeDirParents($a_dir)
Create a new directory and all parent directories.
const MT_TERMS_DEFINITIONS
Class iQuestionCondition.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
Interface ilObjAnswerScoringAdjustable.
Interface ilObjQuestionScoringAdjustable.
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
global $ilDB
$mobs