ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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
1016 {
1017 $extension = "";
1018 if (preg_match("/.*\\.(\\w+)$/", $filename, $matches))
1019 {
1020 $extension = $matches[1];
1021 }
1022 return md5($filename) . "." . $extension;
1023 }
1024
1025 public function removeTermImage($index)
1026 {
1027 $term = $this->terms[$index];
1028 if (is_object($term))
1029 {
1030 $this->deleteImagefile($term->picture);
1031 $term->picture = null;
1032 }
1033 }
1034
1035 public function removeDefinitionImage($index)
1036 {
1037 $definition = $this->definitions[$index];
1038 if (is_object($definition))
1039 {
1040 $this->deleteImagefile($definition->picture);
1041 $definition->picture = null;
1042 }
1043 }
1044
1045
1053 {
1054 $deletename = $filename;
1055 $result = @unlink($this->getImagePath().$deletename);
1056 $result = $result & @unlink($this->getImagePath().$this->getThumbPrefix() . $deletename);
1057 return $result;
1058 }
1059
1068 function setImageFile($image_tempfilename, $image_filename, $previous_filename = '')
1069 {
1070 $result = TRUE;
1071 if (strlen($image_tempfilename))
1072 {
1073 $image_filename = str_replace(" ", "_", $image_filename);
1074 $imagepath = $this->getImagePath();
1075 if (!file_exists($imagepath))
1076 {
1077 ilUtil::makeDirParents($imagepath);
1078 }
1079 $savename = $image_filename;
1080 if (!ilUtil::moveUploadedFile($image_tempfilename, $savename, $imagepath.$savename))
1081 {
1082 $result = FALSE;
1083 }
1084 else
1085 {
1086 // create thumbnail file
1087 $thumbpath = $imagepath . $this->getThumbPrefix() . $savename;
1088 ilUtil::convertImage($imagepath.$savename, $thumbpath, "JPEG", $this->getThumbGeometry());
1089 }
1090 if ($result && (strcmp($image_filename, $previous_filename) != 0) && (strlen($previous_filename)))
1091 {
1092 $this->deleteImagefile($previous_filename);
1093 }
1094 }
1095 return $result;
1096 }
1097
1099 {
1100 $postData = $_POST['matching'][$this->getId()];
1101
1102 $matchings = array();
1103
1104 foreach( $this->getDefinitions() as $definition )
1105 {
1106 if( isset($postData[$definition->identifier]) )
1107 {
1108 foreach( $this->getTerms() as $term )
1109 {
1110 if( isset($postData[$definition->identifier][$term->identifier]) )
1111 {
1112 if( !is_array($postData[$definition->identifier]) )
1113 {
1114 $postData[$definition->identifier] = array();
1115 }
1116
1117 $matchings[$definition->identifier][] = $term->identifier;
1118 }
1119 }
1120 }
1121 }
1122
1123 return $matchings;
1124 }
1125
1126 private function checkSubmittedMatchings($submittedMatchings)
1127 {
1128 if( $this->getMatchingMode() == self::MATCHING_MODE_N_ON_N )
1129 {
1130 return true;
1131 }
1132
1133 $handledTerms = array();
1134
1135 foreach( $submittedMatchings as $definition => $terms )
1136 {
1137 if( count($terms) > 1 )
1138 {
1139 ilUtil::sendFailure($this->lng->txt("multiple_matching_values_selected"), true);
1140 return false;
1141 }
1142
1143 foreach( $terms as $i => $term )
1144 {
1145 if( isset($handledTerms[$term]) )
1146 {
1147 ilUtil::sendFailure($this->lng->txt("duplicate_matching_values_selected"), true);
1148 return false;
1149 }
1150
1151 $handledTerms[$term] = $term;
1152 }
1153 }
1154
1155 return true;
1156 }
1157
1166 public function saveWorkingData($active_id, $pass = NULL, $authorized = true)
1167 {
1168 global $ilDB;
1169
1170 $submittedMatchings = $this->fetchSubmittedMatchingsFromPost();
1171 $submittedMatchingsValid = $this->checkSubmittedMatchings($submittedMatchings);
1172
1173 $matchingsExist = false;
1174
1175 if ($submittedMatchingsValid)
1176 {
1177 if (is_null($pass))
1178 {
1179 include_once "./Modules/Test/classes/class.ilObjTest.php";
1180 $pass = ilObjTest::_getPass($active_id);
1181 }
1182
1183 $this->getProcessLocker()->requestUserSolutionUpdateLock();
1184
1185 $affectedRows = $this->removeCurrentSolution($active_id, $pass, $authorized);
1186
1187 foreach( $submittedMatchings as $definition => $terms )
1188 {
1189 foreach( $terms as $i => $term )
1190 {
1191 $affectedRows = $this->saveCurrentSolution($active_id, $pass, $term, $definition, $authorized);
1192
1193 $matchingsExist = true;
1194 }
1195 }
1196
1197 $this->getProcessLocker()->releaseUserSolutionUpdateLock();
1198
1199 $saveWorkingDataResult = true;
1200 }
1201 else
1202 {
1203 $saveWorkingDataResult = false;
1204 }
1205
1206 include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1208 {
1209 if( $matchingsExist )
1210 {
1211 $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1212 }
1213 else
1214 {
1215 $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1216 }
1217 }
1218
1219 return $saveWorkingDataResult;
1220 }
1221
1222 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1223 {
1224 $submittedMatchings = $this->fetchSubmittedMatchingsFromPost();
1225
1226 if( $this->checkSubmittedMatchings($submittedMatchings) )
1227 {
1228 $previewSession->setParticipantsSolution($submittedMatchings);
1229 }
1230 }
1231
1240 protected function reworkWorkingData($active_id, $pass, $obligationsAnswered)
1241 {
1242 // nothing to rework!
1243 }
1244
1245 public function getRandomId()
1246 {
1247 mt_srand((double)microtime()*1000000);
1248 $random_number = mt_rand(1, 100000);
1249 $found = FALSE;
1250 while ($found)
1251 {
1252 $found = FALSE;
1253 foreach ($this->matchingpairs as $key => $pair)
1254 {
1255 if (($pair->term->identifier == $random_number) || ($pair->definition->identifier == $random_number))
1256 {
1257 $found = TRUE;
1258 $random_number++;
1259 }
1260 }
1261 }
1262 return $random_number;
1263 }
1264
1271 public function setShuffle($shuffle = true)
1272 {
1273 switch ($shuffle)
1274 {
1275 case 0:
1276 case 1:
1277 case 2:
1278 case 3:
1279 $this->shuffle = $shuffle;
1280 break;
1281 default:
1282 $this->shuffle = 1;
1283 break;
1284 }
1285 }
1286
1292 public function getQuestionType()
1293 {
1294 return "assMatchingQuestion";
1295 }
1296
1302 public function getAdditionalTableName()
1303 {
1304 return "qpl_qst_matching";
1305 }
1306
1312 public function getAnswerTableName()
1313 {
1314 return array("qpl_a_matching", "qpl_a_mterm");
1315 }
1316
1322 {
1323 return parent::getRTETextWithMediaObjects();
1324 }
1325
1329 public function &getMatchingPairs()
1330 {
1331 return $this->matchingpairs;
1332 }
1333
1346 public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
1347 {
1348 include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
1349 $solutions = $this->getSolutionValues($active_id, $pass);
1350 $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
1351 $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
1352 $imagepath = $this->getImagePath();
1353 $i = 1;
1354 foreach ($solutions as $solution)
1355 {
1356 $matches_written = FALSE;
1357 foreach ($this->getMatchingPairs() as $idx => $pair)
1358 {
1359 if (!$matches_written) $worksheet->writeString($startrow + $i, 1, ilExcelUtils::_convert_text($this->lng->txt("matches")));
1360 $matches_written = TRUE;
1361 if ($pair->definition->identifier == $solution["value2"])
1362 {
1363 if (strlen($pair->definition->text))
1364 {
1365 $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($pair->definition->text));
1366 }
1367 else
1368 {
1369 $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($pair->definition->picture));
1370 }
1371 }
1372 if ($pair->term->identifier == $solution["value1"])
1373 {
1374 if (strlen($pair->term->text))
1375 {
1376 $worksheet->writeString($startrow + $i, 2, ilExcelUtils::_convert_text($pair->term->text));
1377 }
1378 else
1379 {
1380 $worksheet->writeString($startrow + $i, 2, ilExcelUtils::_convert_text($pair->term->picture));
1381 }
1382 }
1383 }
1384 $i++;
1385 }
1386 return $startrow + $i + 1;
1387 }
1388
1394 public function getThumbGeometry()
1395 {
1396 return $this->thumb_geometry;
1397 }
1398
1404 public function getThumbSize()
1405 {
1406 return $this->getThumbGeometry();
1407 }
1408
1414 public function setThumbGeometry($a_geometry)
1415 {
1416 $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1417 }
1418
1422 public function rebuildThumbnails()
1423 {
1424 foreach ($this->terms as $term)
1425 {
1426 if (strlen($term->picture)) $this->generateThumbForFile($this->getImagePath(), $term->picture);
1427 }
1428 foreach ($this->definitions as $definition)
1429 {
1430 if (strlen($definition->picture)) $this->generateThumbForFile($this->getImagePath(), $definition->picture);
1431 }
1432 }
1433
1434 public function getThumbPrefix()
1435 {
1436 return "thumb.";
1437 }
1438
1439 protected function generateThumbForFile($path, $file)
1440 {
1441 $filename = $path . $file;
1442 if (@file_exists($filename))
1443 {
1444 $thumbpath = $path . $this->getThumbPrefix() . $file;
1445 $path_info = @pathinfo($filename);
1446 $ext = "";
1447 switch (strtoupper($path_info['extension']))
1448 {
1449 case 'PNG':
1450 $ext = 'PNG';
1451 break;
1452 case 'GIF':
1453 $ext = 'GIF';
1454 break;
1455 default:
1456 $ext = 'JPEG';
1457 break;
1458 }
1459 ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1460 }
1461 }
1462
1467 public function toJSON()
1468 {
1469 $result = array();
1470
1471 $result['id'] = (int) $this->getId();
1472 $result['type'] = (string) $this->getQuestionType();
1473 $result['title'] = (string) $this->getTitle();
1474 $result['question'] = $this->formatSAQuestion($this->getQuestion());
1475 $result['nr_of_tries'] = (int) $this->getNrOfTries();
1476 $result['matching_mode'] = $this->getMatchingMode();
1477 $result['shuffle'] = true;
1478 $result['feedback'] = array(
1479 'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1480 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1481 );
1482
1483 $terms = array();
1484 foreach ($this->getTerms() as $term)
1485 {
1486 $terms[] = array(
1487 "text" => $this->formatSAQuestion($term->text),
1488 "id" =>(int)$this->getId().$term->identifier
1489 );
1490 }
1491 $result['terms'] = $terms;
1492
1493 // alex 9.9.2010 as a fix for bug 6513 I added the question id
1494 // to the "def_id" in the array. The $pair->definition->identifier is not
1495 // unique, since it gets it value from the morder table field
1496 // this value is not changed, when a question is copied.
1497 // thus copying the same question on a page results in problems
1498 // when the second one (the copy) is answered.
1499
1500 $definitions = array();
1501 foreach ($this->getDefinitions() as $def)
1502 {
1503 $definitions[] = array(
1504 "text" => $this->formatSAQuestion((string) $def->text),
1505 "id" => (int) $this->getId().$def->identifier
1506 );
1507 }
1508 $result['definitions'] = $definitions;
1509
1510 // #10353
1511 $matchings = array();
1512 foreach ($this->getMatchingPairs() as $pair)
1513 {
1514// fau: fixLmMatchingPoints - ignore matching pairs with 0 or negative points
1515 if ($pair->points <= 0)
1516 {
1517 continue;
1518 }
1519// fau.
1520
1521 $pid = $pair->definition->identifier;
1522 if( $this->getMatchingMode() == self::MATCHING_MODE_N_ON_N )
1523 {
1524 $pid .= '::'.$pair->term->identifier;
1525 }
1526
1527 if( !isset($matchings[$pid]) || $matchings[$pid]["points"] < $pair->points )
1528 {
1529 $matchings[$pid] = array(
1530 "term_id" => (int) $this->getId().$pair->term->identifier,
1531 "def_id" => (int) $this->getId().$pair->definition->identifier,
1532 "points" => (int) $pair->points
1533 );
1534 }
1535 }
1536
1537 $result['matchingPairs'] = array_values($matchings);
1538
1539 $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1540 $result['mobs'] = $mobs;
1541
1542 global $lng;
1543 $lng->loadLanguageModule('assessment');
1544 $result['reset_button_label'] = $lng->txt("reset_terms");
1545
1546 return json_encode($result);
1547 }
1548
1550 {
1551 return true;
1552 }
1553
1554 public function supportsNonJsOutput()
1555 {
1556 return false;
1557 }
1558
1560 {
1561 $this->matchingMode = $matchingMode;
1562 }
1563
1564 public function getMatchingMode()
1565 {
1566 return $this->matchingMode;
1567 }
1568
1573 protected function calculateReachedPointsForSolution($found_values)
1574 {
1575 $points = 0;
1576 foreach($found_values as $definition => $terms)
1577 {
1578 foreach($terms as $term)
1579 {
1580 foreach($this->matchingpairs as $pair)
1581 {
1582 if($pair->definition->identifier == $definition && $pair->term->identifier == $term)
1583 {
1584 $points += $pair->points;
1585 }
1586 }
1587 }
1588 }
1589 return $points;
1590 }
1591
1600 public function getOperators($expression)
1601 {
1602 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1604 }
1605
1610 public function getExpressionTypes()
1611 {
1612 return array(
1617 );
1618 }
1627 public function getUserQuestionResult($active_id, $pass)
1628 {
1630 global $ilDB;
1631 $result = new ilUserQuestionResult($this, $active_id, $pass);
1632
1633 $data = $ilDB->queryF(
1634 "SELECT morder FROM qpl_a_mdef WHERE question_fi = %s ORDER BY def_id",
1635 array("integer"),
1636 array($this->getId())
1637 );
1638
1639 $definitions = array();
1640 for($index=1; $index <= $ilDB->numRows($data); ++$index)
1641 {
1642 $row = $ilDB->fetchAssoc($data);
1643 $definitions[$row["morder"]] = $index;
1644 }
1645
1646 $data = $ilDB->queryF(
1647 "SELECT ident FROM qpl_a_mterm WHERE question_fi = %s ORDER BY term_id",
1648 array("integer"),
1649 array($this->getId())
1650 );
1651
1652 $terms = array();
1653 for($index=1; $index <= $ilDB->numRows($data); ++$index)
1654 {
1655 $row = $ilDB->fetchAssoc($data);
1656 $terms[$row["ident"]] = $index;
1657 }
1658
1659 $maxStep = $this->lookupMaxStep($active_id, $pass);
1660
1661 if( $maxStep !== null )
1662 {
1663 $data = $ilDB->queryF(
1664 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1665 array("integer", "integer", "integer","integer"),
1666 array($active_id, $pass, $this->getId(), $maxStep)
1667 );
1668 }
1669 else
1670 {
1671 $data = $ilDB->queryF(
1672 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1673 array("integer", "integer", "integer"),
1674 array($active_id, $pass, $this->getId())
1675 );
1676 }
1677
1678 while($row = $ilDB->fetchAssoc($data))
1679 {
1680 if($row["value1"] > 0)
1681 {
1682 $result->addKeyValue($definitions[$row["value2"]],$terms[$row["value1"]]);
1683 }
1684 }
1685
1686 $points = $this->calculateReachedPoints($active_id, $pass);
1687 $max_points = $this->getMaximumPoints();
1688
1689 $result->setReachedPercentage(($points/$max_points) * 100);
1690
1691 return $result;
1692 }
1693
1702 public function getAvailableAnswerOptions($index = null)
1703 {
1704 if($index !== null)
1705 {
1706 return $this->getMatchingPair($index);
1707 }
1708 else
1709 {
1710 return $this->getMatchingPairs();
1711 }
1712 }
1713
1717 protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1718 {
1719 parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1720
1721 $origImagePath = $this->buildImagePath($origQuestionId, $origParentObjId);
1722 $dupImagePath = $this->buildImagePath($dupQuestionId, $dupParentObjId);
1723
1724 ilUtil::delDir($origImagePath);
1725 if(is_dir($dupImagePath))
1726 {
1727 ilUtil::makeDirParents($origImagePath);
1728 ilUtil::rCopy($dupImagePath, $origImagePath);
1729 }
1730 }
1731}
$result
print $file
$filename
Definition: buildRTE.php:89
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...
__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)
Reworks the allready saved working data if neccessary.
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.
getDefinitionCount()
Returns the number of definitions.
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
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.
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.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
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.
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)
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
setAuthor($author="")
Sets the authors name of the assQuestion object.
static isFileAvailable($file)
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
removeCurrentSolution($active_id, $pass, $authorized=true, $ignoredSolutionIds=array())
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
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
setQuestion($question="")
Sets the question string of the question object.
_convert_text($a_text, $a_target="has been removed")
_getLogLanguage()
retrieve the log language for assessment logging
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
_getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
_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.
$_POST['username']
Definition: cron.php:12
$data
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.
$path
Definition: index.php:22
global $ilDB
$mobs