ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7 require_once './Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8 require_once './Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9 require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
10 
25 {
43 
49  protected $terms;
50 
51  protected $definitions;
57  public $thumb_geometry = 100;
58 
65 
66  const MATCHING_MODE_1_ON_1 = '1:1';
67  const MATCHING_MODE_N_ON_N = 'n:n';
68 
69  protected $matchingMode = self::MATCHING_MODE_1_ON_1;
70 
85  public function __construct(
86  $title = "",
87  $comment = "",
88  $author = "",
89  $owner = -1,
90  $question = "",
92  ) {
93  parent::__construct($title, $comment, $author, $owner, $question);
94  $this->matchingpairs = array();
95  $this->matching_type = $matching_type;
96  $this->terms = array();
97  $this->definitions = array();
98  }
99 
105  public function isComplete()
106  {
107  if (strlen($this->title)
108  && $this->author
109  && $this->question
110  && count($this->matchingpairs)
111  && $this->getMaximumPoints() > 0
112  ) {
113  return true;
114  }
115  return false;
116  }
117 
124  public function saveToDb($original_id = "")
125  {
126  global $DIC;
127  $ilDB = $DIC['ilDB'];
128 
132 
133 
134  parent::saveToDb($original_id);
135  }
136 
137  public function saveAnswerSpecificDataToDb()
138  {
139  global $DIC;
140  $ilDB = $DIC['ilDB'];
141  // delete old terms
142  $ilDB->manipulateF(
143  "DELETE FROM qpl_a_mterm WHERE question_fi = %s",
144  array( 'integer' ),
145  array( $this->getId() )
146  );
147 
148  // delete old definitions
149  $ilDB->manipulateF(
150  "DELETE FROM qpl_a_mdef WHERE question_fi = %s",
151  array( 'integer' ),
152  array( $this->getId() )
153  );
154 
155  $termids = array();
156  // write terms
157  foreach ($this->terms as $key => $term) {
158  $next_id = $ilDB->nextId('qpl_a_mterm');
159  $ilDB->insert('qpl_a_mterm', array(
160  'term_id' => array('integer', $next_id),
161  'question_fi' => array('integer', $this->getId()),
162  'picture' => array('text', $term->picture),
163  'term' => array('text', $term->text),
164  'ident' => array('integer', $term->identifier)
165  ));
166  $termids[$term->identifier] = $next_id;
167  }
168 
169  $definitionids = array();
170  // write definitions
171  foreach ($this->definitions as $key => $definition) {
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(
184  "DELETE FROM qpl_a_matching WHERE question_fi = %s",
185  array( 'integer' ),
186  array( $this->getId() )
187  );
188  $matchingpairs = $this->getMatchingPairs();
189  foreach ($matchingpairs as $key => $pair) {
190  $next_id = $ilDB->nextId('qpl_a_matching');
191  $ilDB->manipulateF(
192  "INSERT INTO qpl_a_matching (answer_id, question_fi, points, term_fi, definition_fi) VALUES (%s, %s, %s, %s, %s)",
193  array( 'integer', 'integer', 'float', 'integer', 'integer' ),
194  array(
195  $next_id,
196  $this->getId(),
197  $pair->points,
198  $termids[$pair->term->identifier],
199  $definitionids[$pair->definition->identifier]
200  )
201  );
202  }
203 
204  $this->rebuildThumbnails();
205  }
206 
208  {
209  global $DIC;
210  $ilDB = $DIC['ilDB'];
211 
212  // save additional data
213 
214  $ilDB->manipulateF(
215  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
216  array( "integer" ),
217  array( $this->getId() )
218  );
219 
220  $ilDB->insert($this->getAdditionalTableName(), array(
221  'question_fi' => array('integer', $this->getId()),
222  'shuffle' => array('text', $this->shuffle),
223  'matching_type' => array('text', $this->matching_type),
224  'thumb_geometry' => array('integer', $this->getThumbGeometry()),
225  'matching_mode' => array('text', $this->getMatchingMode())
226  ));
227  }
228 
235  public function loadFromDb($question_id)
236  {
237  global $DIC;
238  $ilDB = $DIC['ilDB'];
239 
240  $query = "
241  SELECT qpl_questions.*,
242  {$this->getAdditionalTableName()}.*
243  FROM qpl_questions
244  LEFT JOIN {$this->getAdditionalTableName()}
245  ON {$this->getAdditionalTableName()}.question_fi = qpl_questions.question_id
246  WHERE qpl_questions.question_id = %s
247  ";
248 
249  $result = $ilDB->queryF(
250  $query,
251  array('integer'),
252  array($question_id)
253  );
254 
255  if ($result->numRows() == 1) {
256  $data = $ilDB->fetchAssoc($result);
257  $this->setId($question_id);
258  $this->setObjId($data["obj_fi"]);
259  $this->setTitle($data["title"]);
260  $this->setComment($data["description"]);
261  $this->setOriginalId($data["original_id"]);
262  $this->setNrOfTries($data['nr_of_tries']);
263  $this->setAuthor($data["author"]);
264  $this->setPoints($data["points"]);
265  $this->setOwner($data["owner"]);
266  include_once("./Services/RTE/classes/class.ilRTE.php");
267  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
268  $this->setThumbGeometry($data["thumb_geometry"]);
269  $this->setShuffle($data["shuffle"]);
270  $this->setMatchingMode($data['matching_mode'] === null ? self::MATCHING_MODE_1_ON_1 : $data['matching_mode']);
271  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
272 
273  try {
274  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
275  } catch (ilTestQuestionPoolException $e) {
276  }
277  }
278 
279  $termids = array();
280  $result = $ilDB->queryF(
281  "SELECT * FROM qpl_a_mterm WHERE question_fi = %s ORDER BY term_id ASC",
282  array('integer'),
283  array($question_id)
284  );
285  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
286  $this->terms = array();
287  if ($result->numRows() > 0) {
288  while ($data = $ilDB->fetchAssoc($result)) {
289  $term = new assAnswerMatchingTerm($data['term'], $data['picture'], $data['ident']);
290  array_push($this->terms, $term);
291  $termids[$data['term_id']] = $term;
292  }
293  }
294 
295  $definitionids = array();
296  $result = $ilDB->queryF(
297  "SELECT * FROM qpl_a_mdef WHERE question_fi = %s ORDER BY def_id ASC",
298  array('integer'),
299  array($question_id)
300  );
301  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
302  $this->definitions = array();
303  if ($result->numRows() > 0) {
304  while ($data = $ilDB->fetchAssoc($result)) {
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(
313  "SELECT * FROM qpl_a_matching WHERE question_fi = %s ORDER BY answer_id",
314  array('integer'),
315  array($question_id)
316  );
317  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php";
318  if ($result->numRows() > 0) {
319  while ($data = $ilDB->fetchAssoc($result)) {
320  array_push($this->matchingpairs, new assAnswerMatchingPair($termids[$data['term_fi']], $definitionids[$data['definition_fi']], $data['points']));
321  }
322  }
323  parent::loadFromDb($question_id);
324  }
325 
326 
330  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
331  {
332  if ($this->id <= 0) {
333  // The question has not been saved. It cannot be duplicated
334  return;
335  }
336  // duplicate the question in database
337  $this_id = $this->getId();
338  $thisObjId = $this->getObjId();
339 
340  $clone = $this;
341  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
343  $clone->id = -1;
344 
345  if ((int) $testObjId > 0) {
346  $clone->setObjId($testObjId);
347  }
348 
349  if ($title) {
350  $clone->setTitle($title);
351  }
352  if ($author) {
353  $clone->setAuthor($author);
354  }
355  if ($owner) {
356  $clone->setOwner($owner);
357  }
358  if ($for_test) {
359  $clone->saveToDb($original_id);
360  } else {
361  $clone->saveToDb();
362  }
363 
364  // copy question page content
365  $clone->copyPageOfQuestion($this_id);
366  // copy XHTML media objects
367  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
368  // duplicate the image
369  $clone->duplicateImages($this_id, $thisObjId, $clone->getId(), $testObjId);
370 
371  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
372 
373  return $clone->id;
374  }
375 
379  public function copyObject($target_questionpool_id, $title = "")
380  {
381  if ($this->id <= 0) {
382  // The question has not been saved. It cannot be duplicated
383  return;
384  }
385  // duplicate the question in database
386  $clone = $this;
387  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
389  $clone->id = -1;
390  $source_questionpool_id = $this->getObjId();
391  $clone->setObjId($target_questionpool_id);
392  if ($title) {
393  $clone->setTitle($title);
394  }
395  $clone->saveToDb();
396  // copy question page content
397  $clone->copyPageOfQuestion($original_id);
398  // copy XHTML media objects
399  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
400  // duplicate the image
401  $clone->copyImages($original_id, $source_questionpool_id);
402 
403  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
404 
405  return $clone->id;
406  }
407 
408  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
409  {
410  if ($this->id <= 0) {
411  // The question has not been saved. It cannot be duplicated
412  return;
413  }
414 
415  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
416 
417  $sourceQuestionId = $this->id;
418  $sourceParentId = $this->getObjId();
419 
420  // duplicate the question in database
421  $clone = $this;
422  $clone->id = -1;
423 
424  $clone->setObjId($targetParentId);
425 
426  if ($targetQuestionTitle) {
427  $clone->setTitle($targetQuestionTitle);
428  }
429 
430  $clone->saveToDb();
431  // copy question page content
432  $clone->copyPageOfQuestion($sourceQuestionId);
433  // copy XHTML media objects
434  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
435  // duplicate the image
436  $clone->copyImages($sourceQuestionId, $sourceParentId);
437 
438  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
439 
440  return $clone->id;
441  }
442 
443  public function duplicateImages($question_id, $objectId = null)
444  {
445  global $DIC;
446  $ilLog = $DIC['ilLog'];
447  $imagepath = $this->getImagePath();
448  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
449 
450  if ((int) $objectId > 0) {
451  $imagepath_original = str_replace("/$this->obj_id/", "/$objectId/", $imagepath_original);
452  }
453 
454  foreach ($this->terms as $term) {
455  if (strlen($term->picture)) {
456  $filename = $term->picture;
457  if (!file_exists($imagepath)) {
458  ilUtil::makeDirParents($imagepath);
459  }
460  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
461  $ilLog->write("matching question image could not be duplicated: $imagepath_original$filename");
462  }
463  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
464  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
465  $ilLog->write("matching question image thumbnail could not be duplicated: $imagepath_original" . $this->getThumbPrefix() . $filename);
466  }
467  }
468  }
469  }
470  foreach ($this->definitions as $definition) {
471  if (strlen($definition->picture)) {
472  $filename = $definition->picture;
473  if (!file_exists($imagepath)) {
474  ilUtil::makeDirParents($imagepath);
475  }
476  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
477  $ilLog->write("matching question image could not be duplicated: $imagepath_original$filename");
478  }
479  if (@file_exists($imagepath_original . $this->getThumbPrefix() . $filename)) {
480  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
481  $ilLog->write("matching question image thumbnail could not be duplicated: $imagepath_original" . $this->getThumbPrefix() . $filename);
482  }
483  }
484  }
485  }
486  }
487 
488  public function copyImages($question_id, $source_questionpool)
489  {
490  global $DIC;
491  $ilLog = $DIC['ilLog'];
492 
493  $imagepath = $this->getImagePath();
494  $imagepath_original = str_replace("/$this->id/images", "/$question_id/images", $imagepath);
495  $imagepath_original = str_replace("/$this->obj_id/", "/$source_questionpool/", $imagepath_original);
496  foreach ($this->terms as $term) {
497  if (strlen($term->picture)) {
498  if (!file_exists($imagepath)) {
499  ilUtil::makeDirParents($imagepath);
500  }
501  $filename = $term->picture;
502  if (!@copy($imagepath_original . $filename, $imagepath . $filename)) {
503  $ilLog->write("matching question image could not be copied: $imagepath_original$filename");
504  }
505  if (!@copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename)) {
506  $ilLog->write("matching question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
507  }
508  }
509  }
510  foreach ($this->definitions as $definition) {
511  if (strlen($definition->picture)) {
512  $filename = $definition->picture;
513  if (!file_exists($imagepath)) {
514  ilUtil::makeDirParents($imagepath);
515  }
516 
517  if (assQuestion::isFileAvailable($imagepath_original . $filename)) {
518  copy($imagepath_original . $filename, $imagepath . $filename);
519  } else {
520  $ilLog->write("matching question image could not be copied: $imagepath_original$filename");
521  }
522 
523  if (assQuestion::isFileAvailable($imagepath_original . $this->getThumbPrefix() . $filename)) {
524  copy($imagepath_original . $this->getThumbPrefix() . $filename, $imagepath . $this->getThumbPrefix() . $filename);
525  } else {
526  $ilLog->write("matching question image thumbnail could not be copied: $imagepath_original" . $this->getThumbPrefix() . $filename);
527  }
528  }
529  }
530  }
531 
542  public function insertMatchingPair($position, $term = null, $definition = null, $points = 0.0)
543  {
544  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php";
545  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
546  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
547  if (is_null($term)) {
548  $term = new assAnswerMatchingTerm();
549  }
550  if (is_null($definition)) {
551  $definition = new assAnswerMatchingDefinition();
552  }
553  $pair = new assAnswerMatchingPair($term, $definition, $points);
554  if ($position < count($this->matchingpairs)) {
555  $part1 = array_slice($this->matchingpairs, 0, $position);
556  $part2 = array_slice($this->matchingpairs, $position);
557  $this->matchingpairs = array_merge($part1, array($pair), $part2);
558  } else {
559  array_push($this->matchingpairs, $pair);
560  }
561  }
562 
574  public function addMatchingPair($term = null, $definition = null, $points = 0.0)
575  {
576  require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingPair.php';
577  require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php';
578  require_once './Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php';
579  if (is_null($term)) {
580  $term = new assAnswerMatchingTerm();
581  }
582  if (is_null($definition)) {
583  $definition = new assAnswerMatchingDefinition();
584  }
585  $pair = new assAnswerMatchingPair($term, $definition, $points);
586  array_push($this->matchingpairs, $pair);
587  }
588 
592  public function getTermWithIdentifier($a_identifier)
593  {
594  foreach ($this->terms as $term) {
595  if ($term->identifier == $a_identifier) {
596  return $term;
597  }
598  }
599  return null;
600  }
601 
605  public function getDefinitionWithIdentifier($a_identifier)
606  {
607  foreach ($this->definitions as $definition) {
608  if ($definition->identifier == $a_identifier) {
609  return $definition;
610  }
611  }
612  return null;
613  }
614 
623  public function getMatchingPair($index = 0)
624  {
625  if ($index < 0) {
626  return null;
627  }
628  if (count($this->matchingpairs) < 1) {
629  return null;
630  }
631  if ($index >= count($this->matchingpairs)) {
632  return null;
633  }
634  return $this->matchingpairs[$index];
635  }
636 
644  public function deleteMatchingPair($index = 0)
645  {
646  if ($index < 0) {
647  return;
648  }
649  if (count($this->matchingpairs) < 1) {
650  return;
651  }
652  if ($index >= count($this->matchingpairs)) {
653  return;
654  }
655  unset($this->matchingpairs[$index]);
656  $this->matchingpairs = array_values($this->matchingpairs);
657  }
658 
663  public function flushMatchingPairs()
664  {
665  $this->matchingpairs = array();
666  }
667 
674  public function getMatchingPairCount()
675  {
676  return count($this->matchingpairs);
677  }
678 
685  public function getTerms()
686  {
687  return $this->terms;
688  }
689 
696  public function getDefinitions()
697  {
698  return $this->definitions;
699  }
700 
707  public function getTermCount()
708  {
709  return count($this->terms);
710  }
711 
718  public function getDefinitionCount()
719  {
720  return count($this->definitions);
721  }
722 
729  public function addTerm($term)
730  {
731  array_push($this->terms, $term);
732  }
733 
740  public function addDefinition($definition)
741  {
742  array_push($this->definitions, $definition);
743  }
744 
751  public function insertTerm($position, $term = null)
752  {
753  if (is_null($term)) {
754  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingTerm.php";
755  $term = new assAnswerMatchingTerm();
756  }
757  if ($position < count($this->terms)) {
758  $part1 = array_slice($this->terms, 0, $position);
759  $part2 = array_slice($this->terms, $position);
760  $this->terms = array_merge($part1, array($term), $part2);
761  } else {
762  array_push($this->terms, $term);
763  }
764  }
765 
772  public function insertDefinition($position, $definition = null)
773  {
774  if (is_null($definition)) {
775  include_once "./Modules/TestQuestionPool/classes/class.assAnswerMatchingDefinition.php";
776  $definition = new assAnswerMatchingDefinition();
777  }
778  if ($position < count($this->definitions)) {
779  $part1 = array_slice($this->definitions, 0, $position);
780  $part2 = array_slice($this->definitions, $position);
781  $this->definitions = array_merge($part1, array($definition), $part2);
782  } else {
783  array_push($this->definitions, $definition);
784  }
785  }
786 
791  public function flushTerms()
792  {
793  $this->terms = array();
794  }
795 
800  public function flushDefinitions()
801  {
802  $this->definitions = array();
803  }
804 
811  public function deleteTerm($position)
812  {
813  unset($this->terms[$position]);
814  $this->terms = array_values($this->terms);
815  }
816 
823  public function deleteDefinition($position)
824  {
825  unset($this->definitions[$position]);
826  $this->definitions = array_values($this->definitions);
827  }
828 
836  public function setTerm($term, $index)
837  {
838  $this->terms[$index] = $term;
839  }
840 
851  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
852  {
853  if ($returndetails) {
854  throw new ilTestException('return details not implemented for ' . __METHOD__);
855  }
856 
857  global $DIC;
858  $ilDB = $DIC['ilDB'];
859 
860  $found_values = array();
861  if (is_null($pass)) {
862  $pass = $this->getSolutionMaxPass($active_id);
863  }
864  $result = $this->getCurrentSolutionResultSet($active_id, $pass, $authorizedSolution);
865  while ($data = $ilDB->fetchAssoc($result)) {
866  if (strcmp($data["value1"], "") != 0) {
867  if (!isset($found_values[$data['value2']])) {
868  $found_values[$data['value2']] = array();
869  }
870 
871  $found_values[$data['value2']][] = $data['value1'];
872  }
873  }
874 
875  $points = $this->calculateReachedPointsForSolution($found_values);
876 
877  return $points;
878  }
879 
883  public function getMaximumPoints()
884  {
885  $points = 0;
886 
887  foreach ($this->getMaximumScoringMatchingPairs() as $pair) {
888  $points += $pair->points;
889  }
890 
891  return $points;
892  }
893 
895  {
896  if ($this->getMatchingMode() == self::MATCHING_MODE_N_ON_N) {
897  return $this->getPositiveScoredMatchingPairs();
898  } elseif ($this->getMatchingMode() == self::MATCHING_MODE_1_ON_1) {
900  }
901 
902  return array();
903  }
904 
906  {
907  $matchingPairs = array();
908 
909  foreach ($this->matchingpairs as $pair) {
910  if ($pair->points <= 0) {
911  continue;
912  }
913 
914  $matchingPairs[] = $pair;
915  }
916 
917  return $matchingPairs;
918  }
919 
921  {
922  $matchingPairsByDefinition = array();
923 
924  foreach ($this->matchingpairs as $pair) {
925  if ($pair->points <= 0) {
926  continue;
927  }
928 
929  $defId = $pair->definition->identifier;
930 
931  if (!isset($matchingPairsByDefinition[$defId])) {
932  $matchingPairsByDefinition[$defId] = $pair;
933  } elseif ($pair->points > $matchingPairsByDefinition[$defId]->points) {
934  $matchingPairsByDefinition[$defId] = $pair;
935  }
936  }
937 
938  return $matchingPairsByDefinition;
939  }
940 
945  public function fetchIndexedValuesFromValuePairs(array $valuePairs)
946  {
947  $indexedValues = array();
948 
949  foreach ($valuePairs as $valuePair) {
950  if (!isset($indexedValues[$valuePair['value2']])) {
951  $indexedValues[$valuePair['value2']] = array();
952  }
953 
954  $indexedValues[$valuePair['value2']][] = $valuePair['value1'];
955  }
956 
957  return $indexedValues;
958  }
959 
969  {
970  $extension = "";
971  if (preg_match("/.*\\.(\\w+)$/", $filename, $matches)) {
972  $extension = $matches[1];
973  }
974  return md5($filename) . "." . $extension;
975  }
976 
977  public function removeTermImage($index)
978  {
979  $term = $this->terms[$index];
980  if (is_object($term)) {
981  $this->deleteImagefile($term->picture);
982  $term->picture = null;
983  }
984  }
985 
986  public function removeDefinitionImage($index)
987  {
988  $definition = $this->definitions[$index];
989  if (is_object($definition)) {
990  $this->deleteImagefile($definition->picture);
991  $definition->picture = null;
992  }
993  }
994 
995 
1002  public function deleteImagefile($filename)
1003  {
1004  $deletename = $filename;
1005  $result = @unlink($this->getImagePath() . $deletename);
1006  $result = $result & @unlink($this->getImagePath() . $this->getThumbPrefix() . $deletename);
1007  return $result;
1008  }
1009 
1018  public function setImageFile($image_tempfilename, $image_filename, $previous_filename = '')
1019  {
1020  $result = true;
1021  if (strlen($image_tempfilename)) {
1022  $image_filename = str_replace(" ", "_", $image_filename);
1023  $imagepath = $this->getImagePath();
1024  if (!file_exists($imagepath)) {
1025  ilUtil::makeDirParents($imagepath);
1026  }
1027  $savename = $image_filename;
1028  if (!ilUtil::moveUploadedFile($image_tempfilename, $savename, $imagepath . $savename)) {
1029  $result = false;
1030  } else {
1031  // create thumbnail file
1032  $thumbpath = $imagepath . $this->getThumbPrefix() . $savename;
1033  ilUtil::convertImage($imagepath . $savename, $thumbpath, "JPEG", $this->getThumbGeometry());
1034  }
1035  if ($result && (strcmp($image_filename, $previous_filename) != 0) && (strlen($previous_filename))) {
1036  $this->deleteImagefile($previous_filename);
1037  }
1038  }
1039  return $result;
1040  }
1041 
1043  {
1044  $postData = $_POST['matching'][$this->getId()];
1045 
1046  $matchings = array();
1047 
1048  foreach ($this->getDefinitions() as $definition) {
1049  if (isset($postData[$definition->identifier])) {
1050  foreach ($this->getTerms() as $term) {
1051  if (isset($postData[$definition->identifier][$term->identifier])) {
1052  if (!is_array($postData[$definition->identifier])) {
1053  $postData[$definition->identifier] = array();
1054  }
1055 
1056  $matchings[$definition->identifier][] = $term->identifier;
1057  }
1058  }
1059  }
1060  }
1061 
1062  return $matchings;
1063  }
1064 
1065  private function checkSubmittedMatchings($submittedMatchings)
1066  {
1067  if ($this->getMatchingMode() == self::MATCHING_MODE_N_ON_N) {
1068  return true;
1069  }
1070 
1071  $handledTerms = array();
1072 
1073  foreach ($submittedMatchings as $definition => $terms) {
1074  if (count($terms) > 1) {
1075  ilUtil::sendFailure($this->lng->txt("multiple_matching_values_selected"), true);
1076  return false;
1077  }
1078 
1079  foreach ($terms as $i => $term) {
1080  if (isset($handledTerms[$term])) {
1081  ilUtil::sendFailure($this->lng->txt("duplicate_matching_values_selected"), true);
1082  return false;
1083  }
1084 
1085  $handledTerms[$term] = $term;
1086  }
1087  }
1088 
1089  return true;
1090  }
1091 
1100  public function saveWorkingData($active_id, $pass = null, $authorized = true)
1101  {
1102  global $DIC;
1103  $ilDB = $DIC['ilDB'];
1104 
1105  $submittedMatchings = $this->fetchSubmittedMatchingsFromPost();
1106  $submittedMatchingsValid = $this->checkSubmittedMatchings($submittedMatchings);
1107 
1108  $matchingsExist = false;
1109 
1110  if ($submittedMatchingsValid) {
1111  if (is_null($pass)) {
1112  include_once "./Modules/Test/classes/class.ilObjTest.php";
1113  $pass = ilObjTest::_getPass($active_id);
1114  }
1115 
1116  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$matchingsExist, $submittedMatchings, $active_id, $pass, $authorized) {
1117  $this->removeCurrentSolution($active_id, $pass, $authorized);
1118 
1119  foreach ($submittedMatchings as $definition => $terms) {
1120  foreach ($terms as $i => $term) {
1121  $this->saveCurrentSolution($active_id, $pass, $term, $definition, $authorized);
1122  $matchingsExist = true;
1123  }
1124  }
1125  });
1126 
1127  $saveWorkingDataResult = true;
1128  } else {
1129  $saveWorkingDataResult = false;
1130  }
1131 
1132  include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1134  if ($matchingsExist) {
1135  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1136  } else {
1137  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1138  }
1139  }
1140 
1141  return $saveWorkingDataResult;
1142  }
1143 
1144  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1145  {
1146  $submittedMatchings = $this->fetchSubmittedMatchingsFromPost();
1147 
1148  if ($this->checkSubmittedMatchings($submittedMatchings)) {
1149  $previewSession->setParticipantsSolution($submittedMatchings);
1150  }
1151  }
1152 
1153  public function getRandomId()
1154  {
1155  mt_srand((double) microtime() * 1000000);
1156  $random_number = mt_rand(1, 100000);
1157  $found = false;
1158  while ($found) {
1159  $found = false;
1160  foreach ($this->matchingpairs as $key => $pair) {
1161  if (($pair->term->identifier == $random_number) || ($pair->definition->identifier == $random_number)) {
1162  $found = true;
1163  $random_number++;
1164  }
1165  }
1166  }
1167  return $random_number;
1168  }
1169 
1176  public function setShuffle($shuffle = true)
1177  {
1178  switch ($shuffle) {
1179  case 0:
1180  case 1:
1181  case 2:
1182  case 3:
1183  $this->shuffle = $shuffle;
1184  break;
1185  default:
1186  $this->shuffle = 1;
1187  break;
1188  }
1189  }
1190 
1196  public function getQuestionType()
1197  {
1198  return "assMatchingQuestion";
1199  }
1200 
1206  public function getAdditionalTableName()
1207  {
1208  return "qpl_qst_matching";
1209  }
1210 
1216  public function getAnswerTableName()
1217  {
1218  return array("qpl_a_matching", "qpl_a_mterm");
1219  }
1220 
1225  public function getRTETextWithMediaObjects()
1226  {
1227  return parent::getRTETextWithMediaObjects();
1228  }
1229 
1233  public function &getMatchingPairs()
1234  {
1235  return $this->matchingpairs;
1236  }
1237 
1241  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1242  {
1243  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1244 
1245  $solutions = $this->getSolutionValues($active_id, $pass);
1246 
1247  $imagepath = $this->getImagePath();
1248  $i = 1;
1249  foreach ($solutions as $solution) {
1250  $matches_written = false;
1251  foreach ($this->getMatchingPairs() as $idx => $pair) {
1252  if (!$matches_written) {
1253  $worksheet->setCell($startrow + $i, 1, $this->lng->txt("matches"));
1254  }
1255  $matches_written = true;
1256  if ($pair->definition->identifier == $solution["value2"]) {
1257  if (strlen($pair->definition->text)) {
1258  $worksheet->setCell($startrow + $i, 0, $pair->definition->text);
1259  } else {
1260  $worksheet->setCell($startrow + $i, 0, $pair->definition->picture);
1261  }
1262  }
1263  if ($pair->term->identifier == $solution["value1"]) {
1264  if (strlen($pair->term->text)) {
1265  $worksheet->setCell($startrow + $i, 2, $pair->term->text);
1266  } else {
1267  $worksheet->setCell($startrow + $i, 2, $pair->term->picture);
1268  }
1269  }
1270  }
1271  $i++;
1272  }
1273 
1274  return $startrow + $i + 1;
1275  }
1276 
1282  public function getThumbGeometry()
1283  {
1284  return $this->thumb_geometry;
1285  }
1286 
1292  public function getThumbSize()
1293  {
1294  return $this->getThumbGeometry();
1295  }
1296 
1302  public function setThumbGeometry($a_geometry)
1303  {
1304  $this->thumb_geometry = ($a_geometry < 1) ? 100 : $a_geometry;
1305  }
1306 
1310  public function rebuildThumbnails()
1311  {
1312  foreach ($this->terms as $term) {
1313  if (strlen($term->picture)) {
1314  $this->generateThumbForFile($this->getImagePath(), $term->picture);
1315  }
1316  }
1317  foreach ($this->definitions as $definition) {
1318  if (strlen($definition->picture)) {
1319  $this->generateThumbForFile($this->getImagePath(), $definition->picture);
1320  }
1321  }
1322  }
1323 
1324  public function getThumbPrefix()
1325  {
1326  return "thumb.";
1327  }
1328 
1329  protected function generateThumbForFile($path, $file)
1330  {
1331  $filename = $path . $file;
1332  if (@file_exists($filename)) {
1333  $thumbpath = $path . $this->getThumbPrefix() . $file;
1334  $path_info = @pathinfo($filename);
1335  $ext = "";
1336  switch (strtoupper($path_info['extension'])) {
1337  case 'PNG':
1338  $ext = 'PNG';
1339  break;
1340  case 'GIF':
1341  $ext = 'GIF';
1342  break;
1343  default:
1344  $ext = 'JPEG';
1345  break;
1346  }
1347  ilUtil::convertImage($filename, $thumbpath, $ext, $this->getThumbGeometry());
1348  }
1349  }
1350 
1355  public function toJSON()
1356  {
1357  $result = array();
1358 
1359  $result['id'] = (int) $this->getId();
1360  $result['type'] = (string) $this->getQuestionType();
1361  $result['title'] = (string) $this->getTitle();
1362  $result['question'] = $this->formatSAQuestion($this->getQuestion());
1363  $result['nr_of_tries'] = (int) $this->getNrOfTries();
1364  $result['matching_mode'] = $this->getMatchingMode();
1365  $result['shuffle'] = true;
1366  $result['feedback'] = array(
1367  'onenotcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), false)),
1368  'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), true))
1369  );
1370 
1371  require_once 'Services/Randomization/classes/class.ilArrayElementShuffler.php';
1372  $this->setShuffler(new ilArrayElementShuffler());
1373  $seed = $this->getShuffler()->getSeed();
1374 
1375  $terms = array();
1376  $this->getShuffler()->setSeed($this->getShuffler()->buildSeedFromString($seed . 'terms'));
1377  foreach ($this->getShuffler()->shuffle($this->getTerms()) as $term) {
1378  $terms[] = array(
1379  "text" => $this->formatSAQuestion($term->text),
1380  "id" => (int) $this->getId() . $term->identifier
1381  );
1382  }
1383  $result['terms'] = $terms;
1384 
1385  // alex 9.9.2010 as a fix for bug 6513 I added the question id
1386  // to the "def_id" in the array. The $pair->definition->identifier is not
1387  // unique, since it gets it value from the morder table field
1388  // this value is not changed, when a question is copied.
1389  // thus copying the same question on a page results in problems
1390  // when the second one (the copy) is answered.
1391 
1392  $definitions = array();
1393  $this->getShuffler()->setSeed($this->getShuffler()->buildSeedFromString($seed . 'definitions'));
1394  foreach ($this->getShuffler()->shuffle($this->getDefinitions()) as $def) {
1395  $definitions[] = array(
1396  "text" => $this->formatSAQuestion((string) $def->text),
1397  "id" => (int) $this->getId() . $def->identifier
1398  );
1399  }
1400  $result['definitions'] = $definitions;
1401 
1402  // #10353
1403  $matchings = array();
1404  foreach ($this->getMatchingPairs() as $pair) {
1405  // fau: fixLmMatchingPoints - ignore matching pairs with 0 or negative points
1406  if ($pair->points <= 0) {
1407  continue;
1408  }
1409  // fau.
1410 
1411  $pid = $pair->definition->identifier;
1412  if ($this->getMatchingMode() == self::MATCHING_MODE_N_ON_N) {
1413  $pid .= '::' . $pair->term->identifier;
1414  }
1415 
1416  if (!isset($matchings[$pid]) || $matchings[$pid]["points"] < $pair->points) {
1417  $matchings[$pid] = array(
1418  "term_id" => (int) $this->getId() . $pair->term->identifier,
1419  "def_id" => (int) $this->getId() . $pair->definition->identifier,
1420  "points" => (int) $pair->points
1421  );
1422  }
1423  }
1424 
1425  $result['matchingPairs'] = array_values($matchings);
1426 
1427  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $this->getId());
1428  $result['mobs'] = $mobs;
1429 
1430  global $DIC;
1431  $lng = $DIC['lng'];
1432  $lng->loadLanguageModule('assessment');
1433  $result['reset_button_label'] = $lng->txt("reset_terms");
1434 
1435  return json_encode($result);
1436  }
1437 
1438  public function supportsJavascriptOutput()
1439  {
1440  return true;
1441  }
1442 
1443  public function supportsNonJsOutput()
1444  {
1445  return false;
1446  }
1447 
1449  {
1450  $this->matchingMode = $matchingMode;
1451  }
1452 
1453  public function getMatchingMode()
1454  {
1455  return $this->matchingMode;
1456  }
1457 
1462  protected function calculateReachedPointsForSolution($found_values)
1463  {
1464  $points = 0;
1465  foreach ($found_values as $definition => $terms) {
1466  foreach ($terms as $term) {
1467  foreach ($this->matchingpairs as $pair) {
1468  if ($pair->definition->identifier == $definition && $pair->term->identifier == $term) {
1469  $points += $pair->points;
1470  }
1471  }
1472  }
1473  }
1474  return $points;
1475  }
1476 
1485  public function getOperators($expression)
1486  {
1487  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1489  }
1490 
1495  public function getExpressionTypes()
1496  {
1497  return array(
1502  );
1503  }
1512  public function getUserQuestionResult($active_id, $pass)
1513  {
1515  global $DIC;
1516  $ilDB = $DIC['ilDB'];
1517  $result = new ilUserQuestionResult($this, $active_id, $pass);
1518 
1519  $data = $ilDB->queryF(
1520  "SELECT ident FROM qpl_a_mdef WHERE question_fi = %s ORDER BY def_id",
1521  array("integer"),
1522  array($this->getId())
1523  );
1524 
1525  $definitions = array();
1526  for ($index = 1; $index <= $ilDB->numRows($data); ++$index) {
1527  $row = $ilDB->fetchAssoc($data);
1528  $definitions[$row["ident"]] = $index;
1529  }
1530 
1531  $data = $ilDB->queryF(
1532  "SELECT ident FROM qpl_a_mterm WHERE question_fi = %s ORDER BY term_id",
1533  array("integer"),
1534  array($this->getId())
1535  );
1536 
1537  $terms = array();
1538  for ($index = 1; $index <= $ilDB->numRows($data); ++$index) {
1539  $row = $ilDB->fetchAssoc($data);
1540  $terms[$row["ident"]] = $index;
1541  }
1542 
1543  $maxStep = $this->lookupMaxStep($active_id, $pass);
1544 
1545  if ($maxStep !== null) {
1546  $data = $ilDB->queryF(
1547  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1548  array("integer", "integer", "integer","integer"),
1549  array($active_id, $pass, $this->getId(), $maxStep)
1550  );
1551  } else {
1552  $data = $ilDB->queryF(
1553  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1554  array("integer", "integer", "integer"),
1555  array($active_id, $pass, $this->getId())
1556  );
1557  }
1558 
1559  while ($row = $ilDB->fetchAssoc($data)) {
1560  if ($row["value1"] > 0) {
1561  $result->addKeyValue($definitions[$row["value2"]], $terms[$row["value1"]]);
1562  }
1563  }
1564 
1565  $points = $this->calculateReachedPoints($active_id, $pass);
1566  $max_points = $this->getMaximumPoints();
1567 
1568  $result->setReachedPercentage(($points / $max_points) * 100);
1569 
1570  return $result;
1571  }
1572 
1581  public function getAvailableAnswerOptions($index = null)
1582  {
1583  if ($index !== null) {
1584  return $this->getMatchingPair($index);
1585  } else {
1586  return $this->getMatchingPairs();
1587  }
1588  }
1589 
1593  protected function afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
1594  {
1595  parent::afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId);
1596 
1597  $origImagePath = $this->buildImagePath($origQuestionId, $origParentObjId);
1598  $dupImagePath = $this->buildImagePath($dupQuestionId, $dupParentObjId);
1599 
1600  ilUtil::delDir($origImagePath);
1601  if (is_dir($dupImagePath)) {
1602  ilUtil::makeDirParents($origImagePath);
1603  ilUtil::rCopy($dupImagePath, $origImagePath);
1604  }
1605  }
1606 }
getThumbGeometry()
Get the thumbnail geometry.
Class for matching question terms.
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getId()
Gets the id of the assQuestion object.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assMatchingQuestion.
static isFileAvailable($file)
getMaximumPoints()
Calculates and Returns the maximum points, a learner can reach answering the question.
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
$path
Definition: aliased.php:25
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question.
Class for matching question pairs.
Class iQuestionCondition.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table.
$result
getTermCount()
Returns the number of terms.
copyObject($target_questionpool_id, $title="")
Copies an assMatchingQuestion.
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
global $DIC
Definition: saml.php:7
deleteMatchingPair($index=0)
Deletes a matching pair with a given index.
Abstract basic class which is to be extended by the concrete assessment question type classes...
afterSyncWithOriginal($origQuestionId, $dupQuestionId, $origParentObjId, $dupParentObjId)
{}
getDefinitionCount()
Returns the number of definitions.
getQuestionType()
Returns the question type of the question.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
setId($id=-1)
Sets the id of the assQuestion object.
flushMatchingPairs()
Deletes all matching pairs.
setImageFile($image_tempfilename, $image_filename, $previous_filename='')
Sets the image file and uploads the image to the object&#39;s image directory.
getEncryptedFilename($filename)
Returns the encrypted save filename of a matching picture Images are saved with an encrypted filename...
flushTerms()
Deletes all terms.
deleteImagefile($filename)
Deletes an imagefile from the system if the file is deleted manually.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
const MT_TERMS_DEFINITIONS
fetchIndexedValuesFromValuePairs(array $valuePairs)
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
getAdditionalTableName()
Returns the name of the additional question data table in the database.
$index
Definition: metadata.php:60
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setNrOfTries($a_nr_of_tries)
deleteTerm($position)
Deletes a term.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
rebuildThumbnails()
Rebuild the thumbnail images with a new thumbnail size.
getObjId()
Get the object id of the container object.
calculateReachedPointsForSolution($found_values)
getDefinitions()
Returns the definitions of the matching question.
loadFromDb($question_id)
Loads a assMatchingQuestion object from a database.
getMatchingPair($index=0)
Returns a matching pair with a given index.
Base Exception for all Exceptions relating to Modules/Test.
Class for matching questions.
duplicateImages($question_id, $objectId=null)
static _getLogLanguage()
retrieve the log language for assessment logging
getTermWithIdentifier($a_identifier)
Returns a term with a given identifier.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
insertMatchingPair($position, $term=null, $definition=null, $points=0.0)
Inserts a matching pair for an matching choice question.
setAuthor($author="")
Sets the authors name of the assQuestion object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question.
$mobs
Class ilUserQuestionResult.
insertDefinition($position, $definition=null)
Inserts a definition.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
setTerm($term, $index)
Sets a specific term.
getMatchingPairCount()
Returns the number of matching pairs.
getExpressionTypes()
Get all available expression types for a specific question.
setShuffle($shuffle=true)
Sets the shuffle flag.
getOperators($expression)
Get all available operations for a specific question.
Interface ilObjAnswerScoringAdjustable.
checkSubmittedMatchings($submittedMatchings)
getQuestion()
Gets the question string of the question object.
static convertImage( $a_from, $a_to, $a_target_format="", $a_geometry="", $a_background_color="")
convert image
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
addDefinition($definition)
Adds a definition.
$query
flushDefinitions()
Deletes all definitions.
insertTerm($position, $term=null)
Inserts a term.
if($session===NULL) $postData
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$filename
Definition: buildRTE.php:89
$row
__construct( $title="", $comment="", $author="", $owner=-1, $question="", $matching_type=MT_TERMS_DEFINITIONS)
assMatchingQuestion constructor
toJSON()
Returns a JSON representation of the question TODO.
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
deleteDefinition($position)
Deletes a definition.
getTerms()
Returns the terms of the matching question.
getDefinitionWithIdentifier($a_identifier)
Returns a definition with a given identifier.
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
removeCurrentSolution($active_id, $pass, $authorized=true)
setThumbGeometry($a_geometry)
Set the thumbnail geometry.
buildImagePath($questionId, $parentObjectId)
global $ilDB
setOriginalId($original_id)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
$i
Definition: disco.tpl.php:19
Class for matching question definitions.
$def
Definition: croninfo.php:21
addMatchingPair($term=null, $definition=null, $points=0.0)
Adds an matching pair for an matching choice question.
getAnswerTableName()
Returns the name of the answer table in the database.
getTitle()
Gets the title string of the assQuestion object.
saveToDb($original_id="")
Saves a assMatchingQuestion object to a database.
& getMatchingPairs()
Returns the matchingpairs array.
copyImages($question_id, $source_questionpool)
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
$key
Definition: croninfo.php:18
setComment($comment="")
Sets the comment string of the assQuestion object.
setShuffler(ilArrayElementShuffler $shuffler)
$_POST["username"]
isComplete()
Returns true, if a matching question is complete for use.
getThumbSize()
Get the thumbnail geometry.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
$data
Definition: bench.php:6