ILIAS  release_4-4 Revision
assClozeTestImport Class Reference

Class for cloze question imports. More...

+ Inheritance diagram for assClozeTestImport:
+ Collaboration diagram for assClozeTestImport:

Public Member Functions

 fromXML (&$item, $questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
 Creates a question from a QTI file. More...
 
- Public Member Functions inherited from assQuestionImport
 assQuestionImport (&$a_object)
 assQuestionImport constructor More...
 
 getFeedbackGeneric ($item)
 
 fromXML (&$item, $questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
 Creates a question from a QTI file. More...
 

Additional Inherited Members

- Data Fields inherited from assQuestionImport
 $object
 
- Protected Member Functions inherited from assQuestionImport
 addGeneralMetadata (ilQTIItem $item)
 
 getQplImportArchivDirectory ()
 returns the full path to extracted qpl import archiv (qpl import dir + qpl archiv subdir) More...
 
 getTstImportArchivDirectory ()
 returns the full path to extracted tst import archiv (tst import dir + tst archiv subdir) More...
 
 fetchAdditionalContentEditingModeInformation ($qtiItem)
 fetches the "additional content editing mode" information from qti item and falls back to ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT when no or invalid information is given More...
 

Detailed Description

Class for cloze question imports.

assClozeTestImport is a class for cloze question imports

Author
Helmut Schottmüller helmu.nosp@m.t.sc.nosp@m.hottm.nosp@m.uell.nosp@m.er@ma.nosp@m.c.co.nosp@m.m
Version
$Id$

Definition at line 15 of file class.assClozeTestImport.php.

Member Function Documentation

◆ fromXML()

assClozeTestImport::fromXML ( $item,
  $questionpool_id,
$tst_id,
$tst_object,
$question_counter,
$import_mapping 
)

Creates a question from a QTI file.

Receives parameters from a QTI parser and creates a valid ILIAS question object

Parameters
object$itemThe QTI item object
integer$questionpool_idThe id of the parent questionpool
integer$tst_idThe id of the parent test if the question is part of a test
object$tst_objectA reference to the parent test object
integer$question_counterA reference to a question counter to count the questions of an imported question pool
array$import_mappingAn array containing references to included ILIAS objects public

Definition at line 30 of file class.assClozeTestImport.php.

References $_SESSION, $GLOBALS, $ilUser, ilRTE\_replaceMediaObjectImageSrc(), ilObjMediaObject\_saveTempFileAsMediaObject(), assQuestionImport\addGeneralMetadata(), CLOZE_NUMERIC, CLOZE_SELECT, CLOZE_TEXT, assQuestionImport\fetchAdditionalContentEditingModeInformation(), FIBTYPE_DECIMAL, FIBTYPE_INTEGER, FIBTYPE_STRING, assQuestionImport\getQplImportArchivDirectory(), and assQuestionImport\getTstImportArchivDirectory().

31  {
32  global $ilUser;
33 
34  // empty session variable for imported xhtml mobs
35  unset($_SESSION["import_mob_xhtml"]);
36  $presentation = $item->getPresentation();
37  $duration = $item->getDuration();
38  $questiontext = array();
39  $shuffle = 0;
40  $now = getdate();
41  $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
42  $gaps = array();
43  foreach ($presentation->order as $entry)
44  {
45  switch ($entry["type"])
46  {
47  case "material":
48 
49  $material = $presentation->material[$entry["index"]];
50  array_push($questiontext, $this->object->QTIMaterialToString($material));
51  break;
52  case "response":
53  $response = $presentation->response[$entry["index"]];
54  $rendertype = $response->getRenderType();
55  array_push($questiontext, "<<" . $response->getIdent() . ">>");
56  switch (strtolower(get_class($response->getRenderType())))
57  {
58  case "ilqtirenderfib":
59  switch ($response->getRenderType()->getFibtype())
60  {
61  case FIBTYPE_DECIMAL:
62  case FIBTYPE_INTEGER:
63  array_push($gaps,
64  array(
65  "ident" => $response->getIdent(),
66  "type" => CLOZE_NUMERIC,
67  "answers" => array(),
68  "minnumber" => $response->getRenderType()->getMinnumber(),
69  "maxnumber" => $response->getRenderType()->getMaxnumber()
70  )
71  );
72  break;
73  default:
74  case FIBTYPE_STRING:
75  array_push($gaps, array("ident" => $response->getIdent(), "type" => CLOZE_TEXT, "answers" => array()));
76  break;
77  }
78  break;
79  case "ilqtirenderchoice":
80  $answers = array();
81  $shuffle = $rendertype->getShuffle();
82  $answerorder = 0;
83  foreach ($rendertype->response_labels as $response_label)
84  {
85  $ident = $response_label->getIdent();
86  $answertext = "";
87  foreach ($response_label->material as $mat)
88  {
89  $answertext .= $this->object->QTIMaterialToString($mat);
90  }
91  $answers[$ident] = array(
92  "answertext" => $answertext,
93  "points" => 0,
94  "answerorder" => $answerorder++,
95  "action" => "",
96  "shuffle" => $rendertype->getShuffle()
97  );
98  }
99  array_push($gaps, array("ident" => $response->getIdent(), "type" => CLOZE_SELECT, "shuffle" => $rendertype->getShuffle(), "answers" => $answers));
100  break;
101  }
102  break;
103  }
104  }
105  $responses = array();
106  $feedbacks = array();
107  $feedbacksgeneric = array();
108  foreach ($item->resprocessing as $resprocessing)
109  {
110  foreach ($resprocessing->respcondition as $respcondition)
111  {
112  $ident = "";
113  $correctness = 1;
114  $conditionvar = $respcondition->getConditionvar();
115  foreach ($conditionvar->order as $order)
116  {
117  switch ($order["field"])
118  {
119  case "varequal":
120  $equals = $conditionvar->varequal[$order["index"]]->getContent();
121  $gapident = $conditionvar->varequal[$order["index"]]->getRespident();
122  break;
123  }
124  }
125  foreach ($respcondition->setvar as $setvar)
126  {
127  if (strcmp($gapident, "") != 0)
128  {
129  foreach ($gaps as $gi => $g)
130  {
131  if (strcmp($g["ident"], $gapident) == 0)
132  {
133  if ($g["type"] == CLOZE_SELECT)
134  {
135  foreach ($gaps[$gi]["answers"] as $ai => $answer)
136  {
137  if (strcmp($answer["answertext"], $equals) == 0)
138  {
139  $gaps[$gi]["answers"][$ai]["action"] = $setvar->getAction();
140  $gaps[$gi]["answers"][$ai]["points"] = $setvar->getContent();
141  }
142  }
143  }
144  else if ($g["type"] == CLOZE_TEXT)
145  {
146  array_push($gaps[$gi]["answers"], array(
147  "answertext" => $equals,
148  "points" => $setvar->getContent(),
149  "answerorder" => count($gaps[$gi]["answers"]),
150  "action" => $setvar->getAction()
151  ));
152  }
153  else if ($g["type"] == CLOZE_NUMERIC)
154  {
155  array_push($gaps[$gi]["answers"], array(
156  "answertext" => $equals,
157  "points" => $setvar->getContent(),
158  "answerorder" => count($gaps[$gi]["answers"]),
159  "action" => $setvar->getAction()
160  ));
161  }
162  }
163  }
164  }
165  }
166 
167  if (count($respcondition->displayfeedback))
168  {
169  foreach ($respcondition->displayfeedback as $feedbackpointer)
170  {
171  if (strlen($feedbackpointer->getLinkrefid()))
172  {
173  foreach ($item->itemfeedback as $ifb)
174  {
175  if (strcmp($ifb->getIdent(), "response_allcorrect") == 0)
176  {
177  // found a feedback for the identifier
178  if (count($ifb->material))
179  {
180  foreach ($ifb->material as $material)
181  {
182  $feedbacksgeneric[1] = $material;
183  }
184  }
185  if ((count($ifb->flow_mat) > 0))
186  {
187  foreach ($ifb->flow_mat as $fmat)
188  {
189  if (count($fmat->material))
190  {
191  foreach ($fmat->material as $material)
192  {
193  $feedbacksgeneric[1] = $material;
194  }
195  }
196  }
197  }
198  }
199  else if (strcmp($ifb->getIdent(), "response_onenotcorrect") == 0)
200  {
201  // found a feedback for the identifier
202  if (count($ifb->material))
203  {
204  foreach ($ifb->material as $material)
205  {
206  $feedbacksgeneric[0] = $material;
207  }
208  }
209  if ((count($ifb->flow_mat) > 0))
210  {
211  foreach ($ifb->flow_mat as $fmat)
212  {
213  if (count($fmat->material))
214  {
215  foreach ($fmat->material as $material)
216  {
217  $feedbacksgeneric[0] = $material;
218  }
219  }
220  }
221  }
222  }
223  else
224  {
225  // found a feedback for the identifier
226  if (count($ifb->material))
227  {
228  foreach ($ifb->material as $material)
229  {
230  $feedbacks[$ifb->getIdent()] = $material;
231  }
232  }
233  if ((count($ifb->flow_mat) > 0))
234  {
235  foreach ($ifb->flow_mat as $fmat)
236  {
237  if (count($fmat->material))
238  {
239  foreach ($fmat->material as $material)
240  {
241  $feedbacks[$ifb->getIdent()] = $material;
242  }
243  }
244  }
245  }
246 
247  }
248  }
249  }
250  }
251  }
252 
253  }
254  }
255 
256  $this->addGeneralMetadata($item);
257  $this->object->setTitle($item->getTitle());
258  $this->object->setNrOfTries($item->getMaxattempts());
259  $this->object->setComment($item->getComment());
260  $this->object->setAuthor($item->getAuthor());
261  $this->object->setOwner($ilUser->getId());
262  $this->object->setObjId($questionpool_id);
263  $this->object->setEstimatedWorkingTime($duration["h"], $duration["m"], $duration["s"]);
264  $textgap_rating = $item->getMetadataEntry("textgaprating");
265  $this->object->setFixedTextLength($item->getMetadataEntry("fixedTextLength"));
266  $this->object->setIdenticalScoring($item->getMetadataEntry("identicalScoring"));
267  if (strlen($textgap_rating) == 0) $textgap_rating = "ci";
268  $this->object->setTextgapRating($textgap_rating);
269  $gaptext = array();
270  foreach ($gaps as $gapidx => $gap)
271  {
272  $gapcontent = array();
273  include_once "./Modules/TestQuestionPool/classes/class.assClozeGap.php";
274  $clozegap = new assClozeGap($gap["type"]);
275  foreach ($gap["answers"] as $index => $answer)
276  {
277  include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
278  $gapanswer = new assAnswerCloze($answer["answertext"], $answer["points"], $answer["answerorder"]);
279  switch ($clozegap->getType())
280  {
281  case CLOZE_SELECT:
282  $clozegap->setShuffle($answer["shuffle"]);
283  break;
284  case CLOZE_NUMERIC:
285  $gapanswer->setLowerBound($gap["minnumber"]);
286  $gapanswer->setUpperBound($gap["maxnumber"]);
287  break;
288  }
289  $clozegap->addItem($gapanswer);
290  array_push($gapcontent, $answer["answertext"]);
291  }
292  $this->object->addGapAtIndex($clozegap, $gapidx);
293  $gaptext[$gap["ident"]] = "[gap]" . join(",", $gapcontent). "[/gap]";
294  }
295  $clozetext = join("", $questiontext);
296  foreach ($gaptext as $idx => $val)
297  {
298  $clozetext = str_replace("<<" . $idx . ">>", $val, $clozetext);
299  }
300  $this->object->setQuestion($clozetext);
301  // additional content editing mode information
302  $this->object->setAdditionalContentEditingMode(
304  );
305  $this->object->saveToDb();
306 
307  // handle the import of media objects in XHTML code
308  foreach ($feedbacks as $ident => $material)
309  {
310  $m = $this->object->QTIMaterialToString($material);
311  $feedbacks[$ident] = $m;
312  }
313  foreach ($feedbacksgeneric as $correctness => $material)
314  {
315  $m = $this->object->QTIMaterialToString($material);
316  $feedbacksgeneric[$correctness] = $m;
317  }
318  $questiontext = $this->object->getQuestion();
319  if (is_array($_SESSION["import_mob_xhtml"]))
320  {
321  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
322  include_once "./Services/RTE/classes/class.ilRTE.php";
323  foreach ($_SESSION["import_mob_xhtml"] as $mob)
324  {
325  if ($tst_id > 0)
326  {
327  $importfile = $this->getTstImportArchivDirectory() . '/' . $mob["uri"];
328  }
329  else
330  {
331  $importfile = $this->getQplImportArchivDirectory() . '/' . $mob["uri"];
332  }
333 
334  $GLOBALS['ilLog']->write(__METHOD__.': import mob from dir: '. $importfile);
335 
336  $media_object =& ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
337  $questiontext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $questiontext);
338  foreach ($feedbacks as $ident => $material)
339  {
340  $feedbacks[$ident] = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $material);
341  }
342  foreach ($feedbacksgeneric as $correctness => $material)
343  {
344  $feedbacksgeneric[$correctness] = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $material);
345  }
346  }
347  }
348  $this->object->setQuestion(ilRTE::_replaceMediaObjectImageSrc($questiontext, 1));
349  foreach ($feedbacks as $ident => $material)
350  {
351  $this->object->feedbackOBJ->importSpecificAnswerFeedback(
352  $this->object->getId(), $ident, ilRTE::_replaceMediaObjectImageSrc($material, 1)
353  );
354  }
355  foreach ($feedbacksgeneric as $correctness => $material)
356  {
357  $this->object->feedbackOBJ->importGenericFeedback(
358  $this->object->getId(), $correctness, ilRTE::_replaceMediaObjectImageSrc($material, 1)
359  );
360  }
361  $this->object->saveToDb();
362  if (count($item->suggested_solutions))
363  {
364  foreach ($item->suggested_solutions as $suggested_solution)
365  {
366  $this->object->setSuggestedSolution($suggested_solution["solution"]->getContent(), $suggested_solution["gap_index"], true);
367  }
368  $this->object->saveToDb();
369  }
370  if ($tst_id > 0)
371  {
372  $q_1_id = $this->object->getId();
373  $question_id = $this->object->duplicate(true, null, null, null, $tst_id);
374  $tst_object->questions[$question_counter++] = $question_id;
375  $import_mapping[$item->getIdent()] = array("pool" => $q_1_id, "test" => $question_id);
376  }
377  else
378  {
379  $import_mapping[$item->getIdent()] = array("pool" => $this->object->getId(), "test" => 0);
380  }
381  }
< a tabindex="-1" style="border-style: none;" href="#" title="Refresh Image" onclick="document.getElementById('siimage').src = './securimage_show.php?sid=' + Math.random(); this.blur(); return false">< img src="./images/refresh.png" alt="Reload Image" height="32" width="32" onclick="this.blur()" align="bottom" border="0"/></a >< br/>< strong > Enter Code *if($_SERVER['REQUEST_METHOD']=='POST' &&@ $_POST['do']=='contact') $_SESSION['ctform']['success']
Class for cloze question numeric answers.
addGeneralMetadata(ilQTIItem $item)
& _saveTempFileAsMediaObject($name, $tmp_name, $upload=TRUE)
Create new media object and update page in db and return new media object.
const CLOZE_TEXT
Cloze question constants.
fetchAdditionalContentEditingModeInformation($qtiItem)
fetches the "additional content editing mode" information from qti item and falls back to ADDITIONAL_...
getQplImportArchivDirectory()
returns the full path to extracted qpl import archiv (qpl import dir + qpl archiv subdir) ...
Class for cloze question gaps.
const CLOZE_SELECT
const FIBTYPE_STRING
$GLOBALS['ct_recipient']
const FIBTYPE_INTEGER
static _replaceMediaObjectImageSrc($a_text, $a_direction=0)
replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
const FIBTYPE_DECIMAL
global $ilUser
Definition: imgupload.php:15
getTstImportArchivDirectory()
returns the full path to extracted tst import archiv (tst import dir + tst archiv subdir) ...
const CLOZE_NUMERIC
+ Here is the call graph for this function:

The documentation for this class was generated from the following file: