ILIAS  trunk Revision v11.0_alpha-1715-g7fc467680fb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.assKprimChoiceExport.php
Go to the documentation of this file.
1 <?php
25 {
29  public $object;
30 
31  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false): string
32  {
33  global $DIC;
34  $ilias = $DIC['ilias'];
35 
36  $a_xml_writer = new ilXmlWriter();
37  // set xml header
38  $a_xml_writer->xmlHeader();
39  $a_xml_writer->xmlStartTag("questestinterop");
40  $attrs = [
41  "ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(),
42  "title" => $this->object->getTitle(),
43  "maxattempts" => $this->object->getNrOfTries()
44  ];
45  $a_xml_writer->xmlStartTag("item", $attrs);
46  // add question description
47  $a_xml_writer->xmlElement("qticomment", null, $this->object->getComment());
48  $a_xml_writer->xmlStartTag("itemmetadata");
49  $a_xml_writer->xmlStartTag("qtimetadata");
50  $a_xml_writer->xmlStartTag("qtimetadatafield");
51  $a_xml_writer->xmlElement("fieldlabel", null, "ILIAS_VERSION");
52  $a_xml_writer->xmlElement("fieldentry", null, $ilias->getSetting("ilias_version"));
53  $a_xml_writer->xmlEndTag("qtimetadatafield");
54  $a_xml_writer->xmlStartTag("qtimetadatafield");
55  $a_xml_writer->xmlElement("fieldlabel", null, "QUESTIONTYPE");
56  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getQuestionType());
57  $a_xml_writer->xmlEndTag("qtimetadatafield");
58  $a_xml_writer->xmlStartTag("qtimetadatafield");
59  $a_xml_writer->xmlElement("fieldlabel", null, "AUTHOR");
60  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAuthor());
61  $a_xml_writer->xmlEndTag("qtimetadatafield");
62 
63  // additional content editing information
64  $this->addAdditionalContentEditingModeInformation($a_xml_writer);
65  $this->addGeneralMetadata($a_xml_writer);
66 
67  $a_xml_writer->xmlStartTag("qtimetadatafield");
68  $a_xml_writer->xmlElement("fieldlabel", null, "answer_type");
69  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAnswerType());
70  $a_xml_writer->xmlEndTag("qtimetadatafield");
71 
72  $a_xml_writer->xmlStartTag("qtimetadatafield");
73  $a_xml_writer->xmlElement("fieldlabel", null, "thumb_size");
74  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getThumbSize());
75  $a_xml_writer->xmlEndTag("qtimetadatafield");
76 
77  $a_xml_writer->xmlStartTag("qtimetadatafield");
78  $a_xml_writer->xmlElement("fieldlabel", null, "option_label_setting");
79  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getOptionLabel());
80  $a_xml_writer->xmlEndTag("qtimetadatafield");
81  $a_xml_writer->xmlStartTag("qtimetadatafield");
82  $a_xml_writer->xmlElement("fieldlabel", null, "custom_true_option_label");
83  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getCustomTrueOptionLabel());
84  $a_xml_writer->xmlEndTag("qtimetadatafield");
85  $a_xml_writer->xmlStartTag("qtimetadatafield");
86  $a_xml_writer->xmlElement("fieldlabel", null, "custom_false_option_label");
87  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getCustomFalseOptionLabel());
88  $a_xml_writer->xmlEndTag("qtimetadatafield");
89 
90  $a_xml_writer->xmlStartTag("qtimetadatafield");
91  $a_xml_writer->xmlElement("fieldlabel", null, "feedback_setting");
92  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getSpecificFeedbackSetting());
93  $a_xml_writer->xmlEndTag("qtimetadatafield");
94 
95  $a_xml_writer->xmlEndTag("qtimetadata");
96  $a_xml_writer->xmlEndTag("itemmetadata");
97 
98  // PART I: qti presentation
99  $attrs = [
100  "label" => $this->object->getTitle()
101  ];
102  $a_xml_writer->xmlStartTag("presentation", $attrs);
103  // add flow to presentation
104  $a_xml_writer->xmlStartTag("flow");
105  // add material with question text to presentation
106  $this->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
107  // add answers to presentation
108  $attrs = [
109  "ident" => "MCMR",
110  "rcardinality" => "Multiple"
111  ];
112  $a_xml_writer->xmlStartTag("response_lid", $attrs);
113  $a_xml_writer = $this->addSuggestedSolution($a_xml_writer);
114  // shuffle output
115  $attrs = [];
116  if ($this->object->isShuffleAnswersEnabled()) {
117  $attrs = [
118  "shuffle" => "Yes"
119  ];
120  } else {
121  $attrs = [
122  "shuffle" => "No"
123  ];
124  }
125  $a_xml_writer->xmlStartTag("render_choice", $attrs);
126 
127  // add answers
128  $answers = $this->object->getAnswers();
129  $akeys = array_keys($answers);
130  foreach ($akeys as $index) {
131  $answer = $this->object->getAnswer($index);
132 
133  $a_xml_writer->xmlStartTag('response_label', ['ident' => $answer->getPosition()]);
134 
135  $image_file = $answer->getImageFile() ?? '';
136  if ($image_file !== '') {
137  $this->addQTIMaterial($a_xml_writer, $answer->getAnswertext(), false, false);
138  $imagetype = "image/jpeg";
139  if (preg_match("/.*\.(png|gif)$/", $image_file, $matches)) {
140  $imagetype = "image/" . $matches[1];
141  }
142  if ($force_image_references) {
143  $attrs = [
144  "imagtype" => $imagetype,
145  "label" => $image_file,
146  "uri" => $answer->getImageWebPath()
147  ];
148  $a_xml_writer->xmlElement("matimage", $attrs);
149  } else {
150  $imagepath = $answer->getImageFsPath();
151  $fh = @fopen($imagepath, "rb");
152  if ($fh != false) {
153  $imagefile = fread($fh, filesize($imagepath));
154  fclose($fh);
155  $base64 = base64_encode($imagefile);
156  $attrs = [
157  "imagtype" => $imagetype,
158  "label" => $image_file,
159  "embedded" => "base64"
160  ];
161  $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
162  }
163  }
164  $a_xml_writer->xmlEndTag("material");
165  } else {
166  $this->addQTIMaterial($a_xml_writer, $answer->getAnswertext());
167  }
168  $a_xml_writer->xmlEndTag("response_label");
169  }
170  $a_xml_writer->xmlEndTag("render_choice");
171  $a_xml_writer->xmlEndTag("response_lid");
172  $a_xml_writer->xmlEndTag("flow");
173  $a_xml_writer->xmlEndTag("presentation");
174 
175  // PART II: qti resprocessing
176 
177  $a_xml_writer->xmlStartTag('resprocessing');
178 
179  $a_xml_writer->xmlStartTag('outcomes');
180  $a_xml_writer->xmlElement('decvar', [
181  'varname' => 'SCORE', 'vartype' => 'Decimal', 'defaultval' => '0',
182  'minvalue' => $this->getMinPoints(), 'maxvalue' => $this->getMaxPoints()
183  ]);
184  $a_xml_writer->xmlEndTag('outcomes');
185 
186 
187  foreach ($answers as $answer) {
188  $a_xml_writer->xmlStartTag('respcondition', ['continue' => 'Yes']);
189 
190  $a_xml_writer->xmlStartTag('conditionvar');
191  $a_xml_writer->xmlElement('varequal', ['respident' => $answer->getPosition()], $answer->getCorrectness());
192  $a_xml_writer->xmlEndTag('conditionvar');
193 
194  $a_xml_writer->xmlElement('displayfeedback', [
195  'feedbacktype' => 'Response', 'linkrefid' => "response_{$answer->getPosition()}"
196  ]);
197 
198  $a_xml_writer->xmlEndTag('respcondition');
199  }
200 
201  $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
202  $this->object->getId(),
203  true
204  );
205 
206  $a_xml_writer->xmlStartTag('respcondition', ['continue' => 'Yes']);
207 
208  $a_xml_writer->xmlStartTag('conditionvar');
209  $a_xml_writer->xmlStartTag('and');
210  foreach ($answers as $answer) {
211  $a_xml_writer->xmlElement('varequal', ['respident' => $answer->getPosition()], $answer->getCorrectness());
212  }
213  $a_xml_writer->xmlEndTag('and');
214  $a_xml_writer->xmlEndTag('conditionvar');
215 
216  $a_xml_writer->xmlElement('setvar', ['action' => 'Add'], $this->object->getPoints());
217 
218  if (strlen($feedback_allcorrect)) {
219  $a_xml_writer->xmlElement('displayfeedback', ['feedbacktype' => 'Response', 'linkrefid' => 'response_allcorrect']);
220  }
221 
222  $a_xml_writer->xmlEndTag('respcondition');
223 
224  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
225  $this->object->getId(),
226  false
227  );
228 
229  $a_xml_writer->xmlStartTag('respcondition', ['continue' => 'Yes']);
230 
231  $a_xml_writer->xmlStartTag('conditionvar');
232  $a_xml_writer->xmlStartTag('or');
233  foreach ($answers as $answer) {
234  $a_xml_writer->xmlStartTag('not');
235  $a_xml_writer->xmlElement('varequal', ['respident' => $answer->getPosition()], $answer->getCorrectness());
236  $a_xml_writer->xmlEndTag('not');
237  }
238  $a_xml_writer->xmlEndTag('or');
239  $a_xml_writer->xmlEndTag('conditionvar');
240 
241  $a_xml_writer->xmlElement('setvar', ['action' => 'Add'], 0);
242 
243  if (strlen($feedback_onenotcorrect)) {
244  $a_xml_writer->xmlElement('displayfeedback', ['feedbacktype' => 'Response', 'linkrefid' => 'response_onenotcorrect']);
245  }
246 
247  $a_xml_writer->xmlEndTag('respcondition');
248 
249  $a_xml_writer->xmlEndTag('resprocessing');
250 
251  foreach ($answers as $answer) {
252  $a_xml_writer->xmlStartTag('itemfeedback', ['ident' => "response_{$answer->getPosition()}", 'view' => 'All']);
253  $a_xml_writer->xmlStartTag('flow_mat');
254 
255  $this->addQTIMaterial($a_xml_writer, $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
256  $this->object->getId(),
257  0,
258  $answer->getPosition()
259  ));
260 
261  $a_xml_writer->xmlEndTag('flow_mat');
262  $a_xml_writer->xmlEndTag('itemfeedback');
263  }
264  if (strlen($feedback_allcorrect)) {
265  $a_xml_writer->xmlStartTag('itemfeedback', ['ident' => 'response_allcorrect', 'view' => 'All']);
266  $a_xml_writer->xmlStartTag('flow_mat');
267 
268  $this->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
269 
270  $a_xml_writer->xmlEndTag('flow_mat');
271  $a_xml_writer->xmlEndTag('itemfeedback');
272  }
273  if (strlen($feedback_onenotcorrect)) {
274  $a_xml_writer->xmlStartTag('itemfeedback', ['ident' => 'response_onenotcorrect', 'view' => 'All']);
275  $a_xml_writer->xmlStartTag('flow_mat');
276 
277  $this->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
278 
279  $a_xml_writer->xmlEndTag('flow_mat');
280  $a_xml_writer->xmlEndTag('itemfeedback');
281  }
282 
283  $a_xml_writer = $this->addSolutionHints($a_xml_writer);
284 
285  $a_xml_writer->xmlEndTag("item");
286  $a_xml_writer->xmlEndTag("questestinterop");
287 
288  $a_xml_writer = $a_xml_writer->xmlDumpMem(false);
289  if (!$a_include_header) {
290  $pos = strpos($a_xml_writer, "?>");
291  $a_xml_writer = substr($a_xml_writer, $pos + 2);
292  }
293  return $a_xml_writer;
294  }
295 
296  private function getMinPoints()
297  {
298  if ($this->object->isScorePartialSolutionEnabled()) {
299  return ($this->object->getPoints() / 2);
300  }
301 
302  return 0;
303  }
304 
305  private function getMaxPoints(): float
306  {
307  return $this->object->getPoints();
308  }
309 }
const IL_INST_ID
Definition: constants.php:40
addQTIMaterial(ilXmlWriter $a_xml_writer, string $a_material, bool $close_material_tag=true, bool $add_mobs=true)
Class for question exports.
addGeneralMetadata(ilXmlWriter $xmlwriter)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
global $DIC
Definition: shib_login.php:22
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
addSuggestedSolution(ilXmlWriter $writer)
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
addSolutionHints(ilXmlWriter $writer)