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