ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
assClozeTestImport Class Reference

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V. More...

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

Public Member Functions

 fromXML (string $importdirectory, int $user_id, ilQTIItem $item, int $questionpool_id, ?int $tst_id, ?ilObject &$tst_object, int &$question_counter, array $import_mapping)
 Creates a question from a QTI file. More...
 
- Public Member Functions inherited from assQuestionImport
 getQuestionId ()
 
 getFeedbackGeneric ($item)
 
 fromXML (string $importdirectory, int $user_id, ilQTIItem $item, int $questionpool_id, ?int $tst_id, ?ilObject &$tst_object, int &$question_counter, array $import_mapping)
 
 importSuggestedSolutions (int $question_id, array $solution_from_import)
 
 QTIMaterialToString (ilQTIMaterial $a_material)
 Reads an QTI material tag and creates a text or XHTML string. More...
 

Protected Member Functions

 buildFeedbackIdentifier ($ident)
 
- Protected Member Functions inherited from assQuestionImport
 fetchIndexFromFeedbackIdent ($feedbackIdent, $prefix='response_')
 
 getFeedbackAnswerSpecific (ilQTIItem $item, $prefix='response_')
 
 addGeneralMetadata (ilQTIItem $item)
 
 fetchLifecycle (ilQTIItem $item)
 
 processNonAbstractedImageReferences ($text, $sourceNic)
 
 fetchAdditionalContentEditingModeInformation ($qtiItem)
 fetches the "additional content editing mode" information from qti item and falls back to ADDITIONAL_CONTENT_EDITING_MODE_RTE when no or invalid information is given More...
 
 findSolutionTypeByValue (string $value)
 
 getSuggestedSolutionsRepo ()
 
 deduceThumbSizeFromImportValue (?int $size)
 
 addQuestionToParentObjectAndBuildMappingEntry (int $questionpool_id, ?int $tst_id, int &$question_counter, ?ilObjTest &$tst_object)
 

Private Attributes

ilDBInterface $db
 

Additional Inherited Members

- Data Fields inherited from assQuestionImport
 $object
 
- Protected Attributes inherited from assQuestionImport
SuggestedSolutionsDatabaseRepository $suggestedsolution_repo = null
 

Detailed Description

This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Learning e.V.

ILIAS is licensed with the GPL-3.0, see https://www.gnu.org/licenses/gpl-3.0.en.html You should have received a copy of said license along with the source code, too.

If this is not the case or you just want to try ILIAS, you'll find us at: https://www.ilias.de https://github.com/ILIAS-eLearning 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 28 of file class.assClozeTestImport.php.

Member Function Documentation

◆ buildFeedbackIdentifier()

assClozeTestImport::buildFeedbackIdentifier (   $ident)
protected
Parameters
string$ident
Returns
ilAssSpecificFeedbackIdentifier

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

379 {
380 $fbIdentifier = new ilAssSpecificFeedbackIdentifier();
381
382 $ident = explode('_', $ident);
383
384 if (count($ident) > 1) {
385 $fbIdentifier->setQuestionIndex($ident[0]);
386 $fbIdentifier->setAnswerIndex($ident[1]);
387 } else {
388 $fbIdentifier->setQuestionIndex($ident[0]);
389 $fbIdentifier->setAnswerIndex(0);
390 }
391
392 return $fbIdentifier;
393 }

◆ fromXML()

assClozeTestImport::fromXML ( string  $importdirectory,
int  $user_id,
ilQTIItem  $item,
int  $questionpool_id,
?int  $tst_id,
?ilObject $tst_object,
int &  $question_counter,
array  $import_mapping 
)

Creates a question from a QTI file.

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

Parameters
ilQTIItem$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 @access public

2024-11-06, sk: This is needed because the question-text is actually saved as the first entry in the material- node.

Reimplemented from assQuestionImport.

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

63 : array {
64 // empty session variable for imported xhtml mobs
65 ilSession::clear('import_mob_xhtml');
66 $presentation = $item->getPresentation();
67
68 $questiontext = $this->processNonAbstractedImageReferences(
69 $item->getMetadataEntry('question') ?? ' ',
70 $item->getIliasSourceNic()
71 );
72
73 $clozetext_array = [];
74 $shuffle = 0;
75 $gaps = [];
76 foreach ($presentation->order as $entry) {
77 switch ($entry['type']) {
78 case 'material':
79
80 $material_string = $this->QTIMaterialToString(
81 $presentation->material[$entry['index']]
82 );
83
84 if ($questiontext === ' ') {
90 $questiontext = $material_string;
91 } else {
92 array_push($clozetext_array, $material_string);
93 }
94
95 break;
96 case 'response':
97 $response = $presentation->response[$entry['index']];
98 $rendertype = $response->getRenderType();
99 array_push($clozetext_array, '<<' . $response->getIdent() . '>>');
100
101 switch (strtolower(get_class($response->getRenderType()))) {
102 case 'ilqtirenderfib':
103 switch ($response->getRenderType()->getFibtype()) {
106 array_push(
107 $gaps,
108 [
109 'ident' => $response->getIdent(),
111 'answers' => [],
112 'minnumber' => $response->getRenderType()->getMinnumber(),
113 'maxnumber' => $response->getRenderType()->getMaxnumber(),
114 'gap_size' => $response->getRenderType()->getMaxchars()
115 ]
116 );
117 break;
118 default:
120 array_push(
121 $gaps,
122 [
123 'ident' => $response->getIdent(),
124 'type' => assClozeGap::TYPE_TEXT,
125 'answers' => [],
126 'gap_size' => $response->getRenderType()->getMaxchars()
127 ]
128 );
129 break;
130 }
131 break;
132 case 'ilqtirenderchoice':
133 $answers = [];
134 $shuffle = $rendertype->getShuffle();
135 $answerorder = 0;
136 foreach ($rendertype->response_labels as $response_label) {
137 $ident = $response_label->getIdent();
138 $answertext = '';
139 foreach ($response_label->material as $mat) {
140 $answertext .= $this->QTIMaterialToString($mat);
141 }
142 $answers[$ident] = [
143 'answertext' => $answertext,
144 'points' => 0,
145 'answerorder' => $answerorder++,
146 'action' => '',
147 'shuffle' => $rendertype->getShuffle()
148 ];
149 }
150 $gaps[] = [
151 'ident' => $response->getIdent(),
152 'type' => assClozeGap::TYPE_SELECT,
153 'shuffle' => $rendertype->getShuffle(),
154 'answers' => $answers
155 ];
156 break;
157 }
158 break;
159 }
160 }
161 $feedbacks = [];
162 $feedbacksgeneric = [];
163 foreach ($item->resprocessing as $resprocessing) {
164 foreach ($resprocessing->respcondition as $respcondition) {
165 $ident = '';
166 $correctness = 1;
167 $conditionvar = $respcondition->getConditionvar();
168 $equals = '';
169 $gapident = '';
170 foreach ($conditionvar->order as $order) {
171 if ($order['field'] === 'varequal') {
172 $equals = $conditionvar->varequal[$order['index']]->getContent();
173 $gapident = $conditionvar->varequal[$order['index']]->getRespident();
174 }
175 }
176 if ($gapident === '') {
177 continue;
178 }
179 foreach ($respcondition->setvar as $setvar) {
180 foreach ($gaps as $gi => $g) {
181 if ($g['ident'] !== $gapident) {
182 continue;
183 }
184 switch ($g['type']) {
186 foreach ($gaps[$gi]['answers'] as $ai => $answer) {
187 if ($answer['answertext'] === $equals) {
188 $gaps[$gi]['answers'][$ai]['action'] = $setvar->getAction();
189 $gaps[$gi]['answers'][$ai]['points'] = $setvar->getContent();
190 }
191 }
192 break;
195 $gaps[$gi]['answers'][] = [
196 'answertext' => $equals,
197 'points' => $setvar->getContent(),
198 'answerorder' => count($gaps[$gi]['answers']),
199 'action' => $setvar->getAction()
200
201 ];
202 break;
203 }
204 }
205 }
206
207 if ($respcondition->displayfeedback === []) {
208 continue;
209 }
210
211 foreach ($respcondition->displayfeedback as $feedbackpointer) {
212 if ($feedbackpointer->getLinkrefid() === '') {
213 continue;
214 }
215 foreach ($item->itemfeedback as $ifb) {
216 switch ($ifb->getIdent()) {
217 case 'response_allcorrect':
218 foreach ($ifb->material as $material) {
219 $feedbacksgeneric[1] = $material;
220 }
221 foreach ($ifb->flow_mat as $fmat) {
222 foreach ($fmat->material as $material) {
223 $feedbacksgeneric[1] = $material;
224 }
225 }
226 break;
227 case 'response_onenotcorrect':
228 foreach ($ifb->material as $material) {
229 $feedbacksgeneric[0] = $material;
230 }
231 foreach ($ifb->flow_mat as $fmat) {
232 foreach ($fmat->material as $material) {
233 $feedbacksgeneric[0] = $material;
234 }
235 }
236 break;
237 default:
238 foreach ($ifb->material as $material) {
239 $feedbacks[$ifb->getIdent()] = $material;
240 }
241 foreach ($ifb->flow_mat as $fmat) {
242 foreach ($fmat->material as $material) {
243 $feedbacks[$ifb->getIdent()] = $material;
244 }
245 }
246 }
247 }
248 }
249 }
250 }
251
252 $this->addGeneralMetadata($item);
253 $this->object->setTitle($item->getTitle());
254 $this->object->setNrOfTries((int) $item->getMaxattempts());
255 $this->object->setComment($item->getComment());
256 $this->object->setAuthor($item->getAuthor());
257 $this->object->setOwner($user_id);
258 $this->object->setObjId($questionpool_id);
259 $textgap_rating = $item->getMetadataEntry('textgaprating') ?? '';
260 $this->object->setFixedTextLength((int) $item->getMetadataEntry('fixedTextLength'));
261 $this->object->setIdenticalScoring((bool) $item->getMetadataEntry('identicalScoring'));
262 $this->object->setFeedbackMode(
263 ($item->getMetadataEntry('feedback_mode') ?? '') !== '' ?
265 );
266 $combinations = json_decode(base64_decode($item->getMetadataEntry('combinations') ?? ''));
267 if ($textgap_rating === '') {
268 $textgap_rating = 'ci';
269 }
270 $this->object->setTextgapRating($textgap_rating);
271 $gaptext = [];
272 foreach ($gaps as $gapidx => $gap) {
273 $gapcontent = [];
274 $clozegap = new assClozeGap($gap['type']);
275 foreach ($gap['answers'] as $answer) {
276 $gapanswer = new assAnswerCloze($answer['answertext'], $answer['points'], $answer['answerorder']);
277 $gapanswer->setGapSize((int) ($gap['gap_size'] ?? 0));
278 switch ($clozegap->getType()) {
280 $clozegap->setShuffle($answer['shuffle']);
281 break;
283 $gapanswer->setLowerBound($gap['minnumber']);
284 $gapanswer->setUpperBound($gap['maxnumber']);
285 break;
286 }
287 $clozegap->setGapSize((int) ($gap['gap_size'] ?? 0));
288 $clozegap->addItem($gapanswer);
289 array_push($gapcontent, $answer['answertext']);
290 }
291 $this->object->addGapAtIndex($clozegap, $gapidx);
292 $gaptext[$gap['ident']] = '[gap]' . join(',', $gapcontent) . '[/gap]';
293 }
294
295 $this->object->setQuestion($questiontext);
296 $clozetext = join('', $clozetext_array);
297
298 foreach ($gaptext as $idx => $val) {
299 $clozetext = str_replace('<<' . $idx . '>>', $val, $clozetext);
300 }
301 $this->object->setClozeTextValue($clozetext);
302
303 // additional content editing mode information
304 $this->object->setAdditionalContentEditingMode(
306 );
307 $this->object->saveToDb();
308
309 if (is_array($combinations) && count($combinations) > 0) {
310 $gap_combinations = new assClozeGapCombination($this->db);
311 $gap_combinations->clearGapCombinationsFromDb($this->object->getId());
312 $gap_combinations->importGapCombinationToDb($this->object->getId(), $combinations);
313 $gap_combinations->loadFromDb($this->object->getId());
314 $this->object->setGapCombinations($gap_combinations);
315 $this->object->setGapCombinationsExists(true);
316 }
317
318 // handle the import of media objects in XHTML code
319 foreach ($feedbacks as $ident => $material) {
320 $m = $this->QTIMaterialToString($material);
321 $feedbacks[$ident] = $m;
322 }
323 foreach ($feedbacksgeneric as $correctness => $material) {
324 $m = $this->QTIMaterialToString($material);
325 $feedbacksgeneric[$correctness] = $m;
326 }
327 if (is_array(ilSession::get('import_mob_xhtml'))) {
328 foreach (ilSession::get('import_mob_xhtml') as $mob) {
329 $importfile = $importdirectory . DIRECTORY_SEPARATOR . $mob['uri'];
330 global $DIC;
331 $DIC['ilLog']->write(__METHOD__ . ': import mob from dir: ' . $importfile);
332
333 $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, false);
334 $questiontext = str_replace('src="' . $mob['mob'] . '"', 'src="' . 'il_' . IL_INST_ID . '_mob_' . $media_object->getId() . '"', $questiontext);
335 $clozetext = str_replace('src="' . $mob['mob'] . '"', 'src="' . 'il_' . IL_INST_ID . '_mob_' . $media_object->getId() . '"', $clozetext);
336 foreach ($feedbacks as $ident => $material) {
337 $feedbacks[$ident] = str_replace('src="' . $mob['mob'] . '"', 'src="' . 'il_' . IL_INST_ID . '_mob_' . $media_object->getId() . '"', $material);
338 }
339 foreach ($feedbacksgeneric as $correctness => $material) {
340 $feedbacksgeneric[$correctness] = str_replace('src="' . $mob['mob'] . '"', 'src="' . 'il_' . IL_INST_ID . '_mob_' . $media_object->getId() . '"', $material);
341 }
342 }
343 }
344 $this->object->setQuestion(ilRTE::_replaceMediaObjectImageSrc($questiontext, 1));
345 $this->object->setClozeTextValue(ilRTE::_replaceMediaObjectImageSrc($clozetext, 1));
346 foreach ($feedbacks as $ident => $material) {
347 $fbIdentifier = $this->buildFeedbackIdentifier($ident);
348 $this->object->feedbackOBJ->importSpecificAnswerFeedback(
349 $this->object->getId(),
350 $fbIdentifier->getQuestionIndex(),
351 $fbIdentifier->getAnswerIndex(),
353 );
354 }
355 foreach ($feedbacksgeneric as $correctness => $material) {
356 $this->object->feedbackOBJ->importGenericFeedback(
357 $this->object->getId(),
358 $correctness,
360 );
361 }
362 $this->object->saveToDb();
363
364 $this->importSuggestedSolutions($this->object->getId(), $item->suggested_solutions);
365 $import_mapping[$item->getIdent()] = $this->addQuestionToParentObjectAndBuildMappingEntry(
366 $questionpool_id,
367 $tst_id,
368 $question_counter,
369 $tst_object
370 );
371 return $import_mapping;
372 }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class for cloze question gaps.
fetchAdditionalContentEditingModeInformation($qtiItem)
fetches the "additional content editing mode" information from qti item and falls back to ADDITIONAL_...
addQuestionToParentObjectAndBuildMappingEntry(int $questionpool_id, ?int $tst_id, int &$question_counter, ?ilObjTest &$tst_object)
QTIMaterialToString(ilQTIMaterial $a_material)
Reads an QTI material tag and creates a text or XHTML string.
processNonAbstractedImageReferences($text, $sourceNic)
addGeneralMetadata(ilQTIItem $item)
importSuggestedSolutions(int $question_id, array $solution_from_import)
const FB_MODE_GAP_QUESTION
constants for different feedback modes (per gap or per gap-answers/options)
static _saveTempFileAsMediaObject(string $name, string $tmp_name, bool $upload=true)
getMetadataEntry(string $a_label)
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)
static clear(string $a_var)
const IL_INST_ID
Definition: constants.php:40
global $DIC
Definition: shib_login.php:26
$response
Definition: xapitoken.php:93

Field Documentation

◆ $db

ilDBInterface assClozeTestImport::$db
private

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


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