ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.assKprimChoiceImport.php
Go to the documentation of this file.
1 <?php
2 
26 {
30  public $object;
31 
32  public function fromXML(
33  string $importdirectory,
34  int $user_id,
35  ilQTIItem $item,
36  int $questionpool_id,
37  ?int $tst_id,
38  ?ilObject &$tst_object,
39  int &$question_counter,
40  array $import_mapping
41  ): array {
42  ilSession::clear('import_mob_xhtml');
43 
44  $shuffle = 0;
45  $answers = [];
46 
47  $presentation = $item->getPresentation();
48  foreach ($presentation->order as $entry) {
49  if ($entry['type'] !== 'response') {
50  continue;
51  }
52 
53  $response = $presentation->response[$entry['index']];
54  $rendertype = $response->getRenderType();
55  if (strtolower(get_class($response->getRenderType())) !== 'ilqtirenderchoice') {
56  continue;
57  }
58 
59  $shuffle = $rendertype->getShuffle();
60  $foundimage = false;
61  foreach ($rendertype->response_labels as $response_label) {
62  $ident = $response_label->getIdent();
63  $answertext = '';
64  $answerimage = [];
65  foreach ($response_label->material as $mat) {
66  $embedded = false;
67  for ($m = 0; $m < $mat->getMaterialCount(); $m++) {
68  $foundmat = $mat->getMaterial($m);
69  if ($foundmat['type'] === 'matimage'
70  && $foundmat['material']->getEmbedded() !== '') {
71  $embedded = true;
72  }
73  }
74  if (!$embedded) {
75  $answertext = $this->QTIMaterialToString($mat);
76  continue;
77  }
78 
79  for ($m = 0; $m < $mat->getMaterialCount(); $m++) {
80  $foundmat = $mat->getMaterial($m);
81  if ($foundmat['type'] === 'mattext') {
82  $answertext .= $foundmat['material']->getContent();
83  }
84  if ($foundmat['type'] === 'matimage') {
85  $foundimage = true;
86  $answerimage = [
87  'imagetype' => $foundmat['material']->getImageType(),
88  'label' => $foundmat['material']->getLabel(),
89  'content' => $foundmat['material']->getContent()
90  ];
91  }
92  }
93  }
94 
95  $answers[$ident] = [
96  'answertext' => $answertext,
97  'imagefile' => $answerimage,
98  'answerorder' => $ident
99  ];
100  }
101  }
102 
103  $feedbacks = [];
104  $feedbacksgeneric = [];
105 
106  foreach ($item->resprocessing as $resprocessing) {
107  foreach ($resprocessing->outcomes->decvar as $decvar) {
108  if ($decvar->getVarname() == 'SCORE') {
109  $this->object->setPoints($decvar->getMaxvalue());
110  $this->object->setScorePartialSolutionEnabled(false);
111  if ($decvar->getMinvalue() > 0) {
112  $this->object->setScorePartialSolutionEnabled(true);
113  }
114  }
115  }
116 
117  foreach ($resprocessing->respcondition as $respcondition) {
118  if ($respcondition->setvar === []) {
119  foreach ($respcondition->getConditionvar()->varequal as $varequal) {
120  $ident = $varequal->respident;
121  $answers[$ident]['correctness'] = (bool) $varequal->getContent();
122  break;
123  }
124 
125  foreach ($respcondition->displayfeedback as $feedbackpointer) {
126  if ($feedbackpointer->getLinkrefid() === '') {
127  continue;
128  }
129  foreach ($item->itemfeedback as $ifb) {
130  if ($ifb->getIdent() !== $feedbackpointer->getLinkrefid()) {
131  continue;
132  }
133 
134  foreach ($ifb->material as $material) {
135  $feedbacks[$ident] = $material;
136  }
137  foreach ($ifb->flow_mat as $fmat) {
138  foreach ($fmat->material as $material) {
139  $feedbacks[$ident] = $material;
140  }
141  }
142  }
143  }
144 
145  continue;
146  }
147 
148  foreach ($respcondition->displayfeedback as $feedbackpointer) {
149  if ($feedbackpointer->getLinkrefid() === '') {
150  continue;
151  }
152 
153  foreach ($item->itemfeedback as $ifb) {
154  if ($ifb->getIdent() === 'response_allcorrect') {
155  foreach ($ifb->material as $material) {
156  $feedbacksgeneric[1] = $material;
157  }
158  foreach ($ifb->flow_mat as $fmat) {
159  foreach ($fmat->material as $material) {
160  $feedbacksgeneric[1] = $material;
161  }
162  }
163  continue;
164  }
165 
166  if ($ifb->getIdent() === 'response_onenotcorrect') {
167  // found a feedback for the identifier
168  foreach ($ifb->material as $material) {
169  $feedbacksgeneric[0] = $material;
170  }
171  foreach ($ifb->flow_mat as $fmat) {
172  foreach ($fmat->material as $material) {
173  $feedbacksgeneric[0] = $material;
174  }
175  }
176  }
177  }
178  }
179  }
180  }
181 
182  $this->addGeneralMetadata($item);
183  $this->object->setTitle($item->getTitle());
184  $this->object->setNrOfTries((int) $item->getMaxattempts());
185  $this->object->setComment($item->getComment());
186  $this->object->setAuthor($item->getAuthor());
187  $this->object->setOwner($user_id);
188  $this->object->setQuestion($this->QTIMaterialToString($item->getQuestiontext()));
189  $this->object->setObjId($questionpool_id);
190  $this->object->setShuffleAnswersEnabled($shuffle);
191  $this->object->setAnswerType($item->getMetadataEntry('answer_type'));
192  $this->object->setOptionLabel($item->getMetadataEntry('option_label_setting'));
193  $this->object->setCustomTrueOptionLabel($item->getMetadataEntry('custom_true_option_label'));
194  $this->object->setCustomFalseOptionLabel($item->getMetadataEntry('custom_false_option_label'));
195  $this->object->setThumbSize(
196  $this->deduceThumbSizeFromImportValue((int) $item->getMetadataEntry('thumb_size'))
197  );
198 
199  $this->object->saveToDb();
200 
201  $answer_objects = [];
202  foreach ($answers as $answer_data) {
203  $answer = new ilAssKprimChoiceAnswer();
204  $answer->setImageFsDir($this->object->getImagePath());
205  $answer->setImageWebDir($this->object->getImagePathWeb());
206  $answer->setPosition($answer_data['answerorder']);
207  $answer->setAnswertext($answer_data['answertext']);
208  $answer->setCorrectness($answer_data['correctness']);
209  if (isset($answer_data['imagefile']['label'])) {
210  $answer->setImageFile($answer_data['imagefile']['label']);
211  }
212  $answer_objects[] = $answer;
213  }
214  $this->object->setAnswers($answer_objects);
215  // additional content editing mode information
216  $this->object->setAdditionalContentEditingMode(
218  );
219 
220  $this->object->saveToDb();
221 
222  foreach ($answers as $answer) {
223  if (!is_array($answer['imagefile']) || $answer['imagefile'] === []) {
224  continue;
225  }
226  $image = base64_decode($answer['imagefile']['content']);
227  $imagepath = $this->object->getImagePath();
228  if (!file_exists($imagepath)) {
229  ilFileUtils::makeDirParents($imagepath);
230  }
231  $imagepath .= $answer['imagefile']['label'];
232  if ($fh = fopen($imagepath, 'wb')) {
233  $imagefile = fwrite($fh, $image);
234  fclose($fh);
235  $this->object->generateThumbForFile(
236  $answer['imagefile']['label'],
237  $this->object->getImagePath(),
238  $this->object->getThumbSize()
239  );
240  }
241  }
242 
243  $feedback_setting = $item->getMetadataEntry('feedback_setting');
244  if (!is_null($feedback_setting)) {
245  $this->object->feedbackOBJ->saveSpecificFeedbackSetting($this->object->getId(), $feedback_setting);
246  $this->object->setSpecificFeedbackSetting($feedback_setting);
247  }
248 
249  // handle the import of media objects in XHTML code
250  foreach ($feedbacks as $ident => $material) {
251  $m = $this->QTIMaterialToString($material);
252  $feedbacks[$ident] = $m;
253  }
254  foreach ($feedbacksgeneric as $correctness => $material) {
255  $m = $this->QTIMaterialToString($material);
256  $feedbacksgeneric[$correctness] = $m;
257  }
258  $questiontext = $this->object->getQuestion();
259  $answers = $this->object->getAnswers();
260  if (is_array(ilSession::get("import_mob_xhtml"))) {
261  foreach (ilSession::get("import_mob_xhtml") as $mob) {
262  $importfile = $importdirectory . DIRECTORY_SEPARATOR . $mob["uri"];
263 
264  global $DIC; /* @var ILIAS\DI\Container $DIC */
265  $DIC['ilLog']->write(__METHOD__ . ': import mob from dir: ' . $importfile);
266 
267  $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, false);
268  ilObjMediaObject::_saveUsage($media_object->getId(), "qpl:html", $this->object->getId());
269  $questiontext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $questiontext);
270  foreach ($answers as $answer_obj) {
271  if ($answer_obj->getAnswertext() === null) {
272  continue;
273  }
274  $answer_obj->setAnswertext(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $answer_obj->getAnswertext()));
275  }
276  foreach ($feedbacks as $ident => $material) {
277  $feedbacks[$ident] = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $material);
278  }
279  foreach ($feedbacksgeneric as $correctness => $material) {
280  $feedbacksgeneric[$correctness] = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $material);
281  }
282  }
283  }
284  $this->object->setQuestion(ilRTE::_replaceMediaObjectImageSrc($questiontext, 1));
285  foreach ($answers as $answer_obj) {
286  if ($answer_obj->getAnswertext() === null) {
287  continue;
288  }
289  $answer_obj->setAnswertext(ilRTE::_replaceMediaObjectImageSrc($answer_obj->getAnswertext(), 1));
290  }
291  foreach ($feedbacks as $ident => $material) {
292  $this->object->feedbackOBJ->importSpecificAnswerFeedback(
293  $this->object->getId(),
294  0,
295  $ident,
297  );
298  }
299  foreach ($feedbacksgeneric as $correctness => $material) {
300  $this->object->feedbackOBJ->importGenericFeedback(
301  $this->object->getId(),
302  $correctness,
304  );
305  }
306  $this->object->saveToDb();
307  $this->importSuggestedSolutions($this->object->getId(), $item->suggested_solutions);
308  $import_mapping[$item->getIdent()] = $this->addQuestionToParentObjectAndBuildMappingEntry(
309  $questionpool_id,
310  $tst_id,
311  $question_counter,
312  $tst_object
313  );
314  return $import_mapping;
315  }
316 }
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static get(string $a_var)
deduceThumbSizeFromImportValue(?int $size)
addGeneralMetadata(ilQTIItem $item)
const IL_INST_ID
Definition: constants.php:40
QTIMaterialToString(ilQTIMaterial $a_material)
Reads an QTI material tag and creates a text or XHTML string.
addQuestionToParentObjectAndBuildMappingEntry(int $questionpool_id, ?int $tst_id, int &$question_counter, ?ilObjTest &$tst_object)
getMetadataEntry(string $a_label)
fetchAdditionalContentEditingModeInformation($qtiItem)
fetches the "additional content editing mode" information from qti item and falls back to ADDITIONAL_...
static _saveUsage(int $a_mob_id, string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
Save usage of mob within another container (e.g.
$response
Definition: xapitoken.php:93
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
global $DIC
Definition: shib_login.php:26
importSuggestedSolutions(int $question_id, array $solution_from_import)
static _saveTempFileAsMediaObject(string $name, string $tmp_name, bool $upload=true)
Class for question imports.
static clear(string $a_var)
fromXML(string $importdirectory, int $user_id, ilQTIItem $item, int $questionpool_id, ?int $tst_id, ?ilObject &$tst_object, int &$question_counter, array $import_mapping)