ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.assClozeTestGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7
24{
25 const OLD_CLOZE_TEST_UI = false;
26
30 private $gapIndex;
31
37 public function __construct($id = -1)
38 {
40 include_once "./Modules/TestQuestionPool/classes/class.assClozeTest.php";
41 $this->object = new assClozeTest();
42 if ($id >= 0) {
43 $this->object->loadFromDb($id);
44 }
45 }
46
47 public function getCommand($cmd)
48 {
49 if (preg_match("/^(removegap|addgap)_(\d+)$/", $cmd, $matches)) {
50 $cmd = $matches[1];
51 $this->gapIndex = $matches[2];
52 }
53 return $cmd;
54 }
55
59 protected function writePostData($always = false)
60 {
61 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
62 if (!$hasErrors) {
63 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
64
65 $cloze_text = $this->object->getHtmlQuestionContentPurifier()->purify($_POST['cloze_text']);
66
67 $cloze_text = $this->removeIndizesFromGapText($cloze_text);
68 $_POST['cloze_text'] = $cloze_text;
69 $this->object->setQuestion($_POST['question']);
70
72 $this->object->setClozeText($_POST["cloze_text"]);
74 //$this->object->flushGaps();
77 return 0;
78 }
79
80 $cloze_text = $_POST['cloze_text'];
81 $cloze_text = $this->applyIndizesToGapText($cloze_text);
82 $_POST['cloze_text'] = $cloze_text;
83 return 1;
84 }
85
87 {
88 if (is_array($_POST['gap'])) {
89 if ($this->ctrl->getCmd() != 'createGaps') {
90 $this->object->clearGapAnswers();
91 }
92
93 foreach ($_POST['gap'] as $idx => $hidden) {
94 $clozetype = $_POST['clozetype_' . $idx];
95
96 $this->object->setGapType($idx, $clozetype);
97
98 switch ($clozetype) {
99 case CLOZE_TEXT:
100
101 $this->object->setGapShuffle($idx, 0);
102
103 if ($this->ctrl->getCmd() != 'createGaps') {
104 if (is_array($_POST['gap_' . $idx]['answer'])) {
105 foreach ($_POST['gap_' . $idx]['answer'] as $order => $value) {
106 $this->object->addGapAnswer($idx, $order, $value);
107 }
108 } else {
109 $this->object->addGapAnswer($idx, 0, '');
110 }
111 }
112
113 if (is_array($_POST['gap_' . $idx]['points'])) {
114 foreach ($_POST['gap_' . $idx]['points'] as $order => $value) {
115 $this->object->setGapAnswerPoints($idx, $order, $value);
116 }
117 }
118
119 if (array_key_exists('gap_' . $idx . '_gapsize', $_POST)) {
120 $this->object->setGapSize($idx, $order, $_POST['gap_' . $idx . '_gapsize']);
121 }
122
123 break;
124
125 case CLOZE_SELECT:
126
127 $this->object->setGapShuffle($idx, (int) (isset($_POST["shuffle_$idx"]) && $_POST["shuffle_$idx"]));
128
129 if ($this->ctrl->getCmd() != 'createGaps') {
130 if (is_array($_POST['gap_' . $idx]['answer'])) {
131 foreach ($_POST['gap_' . $idx]['answer'] as $order => $value) {
132 $this->object->addGapAnswer($idx, $order, $value);
133 }
134 } else {
135 $this->object->addGapAnswer($idx, 0, '');
136 }
137 }
138
139 if (is_array($_POST['gap_' . $idx]['points'])) {
140 foreach ($_POST['gap_' . $idx]['points'] as $order => $value) {
141 $this->object->setGapAnswerPoints($idx, $order, $value);
142 }
143 }
144 break;
145
146 case CLOZE_NUMERIC:
147
148 $this->object->setGapShuffle($idx, 0);
149
150 $gap = $this->object->getGap($idx);
151 if (!$gap) {
152 break;
153 }
154
155 $this->object->getGap($idx)->clearItems();
156
157 if (array_key_exists('gap_' . $idx . '_numeric', $_POST)) {
158 if ($this->ctrl->getCmd() != 'createGaps') {
159 $this->object->addGapAnswer(
160 $idx,
161 0,
162 str_replace(",", ".", $_POST['gap_' . $idx . '_numeric'])
163 );
164 }
165
166 $this->object->setGapAnswerLowerBound(
167 $idx,
168 0,
169 str_replace(",", ".", $_POST['gap_' . $idx . '_numeric_lower'])
170 );
171
172 $this->object->setGapAnswerUpperBound(
173 $idx,
174 0,
175 str_replace(",", ".", $_POST['gap_' . $idx . '_numeric_upper'])
176 );
177
178 $this->object->setGapAnswerPoints($idx, 0, $_POST['gap_' . $idx . '_numeric_points']);
179 } else {
180 if ($this->ctrl->getCmd() != 'createGaps') {
181 $this->object->addGapAnswer($idx, 0, '');
182 }
183
184 $this->object->setGapAnswerLowerBound($idx, 0, '');
185
186 $this->object->setGapAnswerUpperBound($idx, 0, '');
187 }
188
189 if (array_key_exists('gap_' . $idx . '_gapsize', $_POST)) {
190 $this->object->setGapSize($idx, $order, $_POST['gap_' . $idx . '_gapsize']);
191 }
192 break;
193 }
194 $assClozeGapCombinationObject = new assClozeGapCombination();
195 $assClozeGapCombinationObject->clearGapCombinationsFromDb($this->object->getId());
196 if (
197 isset($_POST['gap_combination']) &&
198 is_array($_POST['gap_combination']) &&
199 count($_POST['gap_combination']) > 0
200 ) {
201 $assClozeGapCombinationObject->saveGapCombinationToDb(
202 $this->object->getId(),
203 ilUtil::stripSlashesRecursive($_POST['gap_combination']),
204 ilUtil::stripSlashesRecursive($_POST['gap_combination_values'])
205 );
206 }
207 }
208 if ($this->ctrl->getCmd() != 'createGaps') {
209 $this->object->updateClozeTextFromGaps();
210 }
211 }
212 }
213
215 {
216 $this->object->setClozeText($_POST['cloze_text']);
217 $this->object->setTextgapRating($_POST["textgap_rating"]);
218 $this->object->setIdenticalScoring($_POST["identical_scoring"]);
219 $this->object->setFixedTextLength($_POST["fixedTextLength"]);
220 }
221
227 public function editQuestion($checkonly = false)
228 {
229 $save = $this->isSaveCommand();
230 $this->getQuestionTemplate();
231
232 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
233 $form = new ilPropertyFormGUI();
234 $this->editForm = $form;
235
236 $form->setFormAction($this->ctrl->getFormAction($this));
237 $form->setTitle($this->outQuestionType());
238 $form->setMultipart(false);
239 $form->setTableWidth("100%");
240 $form->setId("assclozetest");
241
242 // title, author, description, question, working time (assessment mode)
243 $this->addBasicQuestionFormProperties($form);
245 $this->populateAnswerSpecificFormPart($form);
246 $this->populateTaxonomyFormSection($form);
247
248 $this->addQuestionFormCommandButtons($form);
249
250 $errors = false;
251
252 if ($save) {
253 $form->setValuesByPost();
254 $errors = !$form->checkInput();
255 $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we
256 // need this if we don't want to have duplication of backslashes
257 if ($errors) {
258 $checkonly = false;
259 }
260 }
261
262 if (!$checkonly) {
263 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
264 }
265 return $errors;
266 }
267
268 public function addBasicQuestionFormProperties($form)
269 {
270 // title
271 $title = new ilTextInputGUI($this->lng->txt("title"), "title");
272 $title->setMaxLength(100);
273 $title->setValue($this->object->getTitle());
274 $title->setRequired(true);
275 $form->addItem($title);
276
277 if (!$this->object->getSelfAssessmentEditingMode()) {
278 // author
279 $author = new ilTextInputGUI($this->lng->txt("author"), "author");
280 $author->setValue($this->object->getAuthor());
281 $author->setRequired(true);
282 $form->addItem($author);
283
284 // description
285 $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
286 $description->setValue($this->object->getComment());
287 $description->setRequired(false);
288 $form->addItem($description);
289 } else {
290 // author as hidden field
291 $hi = new ilHiddenInputGUI("author");
292 $author = ilUtil::prepareFormOutput($this->object->getAuthor());
293 if (trim($author) == "") {
294 $author = "-";
295 }
296 $hi->setValue($author);
297 $form->addItem($hi);
298 }
299
300 // lifecycle
301 $lifecycle = new ilSelectInputGUI($this->lng->txt('qst_lifecycle'), 'lifecycle');
302 $lifecycle->setOptions($this->object->getLifecycle()->getSelectOptions($this->lng));
303 $lifecycle->setValue($this->object->getLifecycle()->getIdentifier());
304 $form->addItem($lifecycle);
305
306 // questiontext
307 $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
308 $question->setValue($this->object->prepareTextareaOutput($this->object->getQuestion()));
309 $question->setRequired(true);
310 $question->setRows(10);
311 $question->setCols(80);
312 if (!$this->object->getSelfAssessmentEditingMode()) {
313 if ($this->object->getAdditionalContentEditingMode() == assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT) {
314 $question->setUseRte(true);
315 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
316 $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
317 $question->addPlugin("latex");
318 $question->addButton("latex");
319 $question->addButton("pastelatex");
320 $question->setRTESupport($this->object->getId(), "qpl", "assessment");
321 }
322 } else {
323 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
325 $question->setUseTagsForRteOnly(false);
326 }
327 $form->addItem($question);
328
329 // $tpl = new ilTemplate("tpl.il_as_qpl_cloze_gap_button_code.html", TRUE, TRUE, "Modules/TestQuestionPool");
330 // $tpl->setVariable('INSERT_GAP', $this->lng->txt('insert_gap'));
331 // $tpl->setVariable('CREATE_GAPS', $this->lng->txt('create_gaps'));
332 // $tpl->parseCurrentBlock();
333 // $button = new ilCustomInputGUI('&nbsp;','');
334 // $button->setHtml($tpl->get());
335 // $form->addItem($button);
336
337 if (!$this->object->getSelfAssessmentEditingMode()) {
338 // duration
339 $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
340 $duration->setShowHours(true);
341 $duration->setShowMinutes(true);
342 $duration->setShowSeconds(true);
343 $ewt = $this->object->getEstimatedWorkingTime();
344 $duration->setHours($ewt["h"]);
345 $duration->setMinutes($ewt["m"]);
346 $duration->setSeconds($ewt["s"]);
347 $duration->setRequired(false);
348 $form->addItem($duration);
349 } else {
350 // number of tries
351 if (strlen($this->object->getNrOfTries())) {
352 $nr_tries = $this->object->getNrOfTries();
353 } else {
354 $nr_tries = $this->object->getDefaultNrOfTries();
355 }
356 /*if ($nr_tries <= 0)
357 {
358 $nr_tries = 1;
359 }*/
360
361 if ($nr_tries < 0) {
362 $nr_tries = 0;
363 }
364
365 $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
366 $ni->setValue($nr_tries);
367 //$ni->setMinValue(1);
368 $ni->setMinValue(0);
369 $ni->setSize(5);
370 $ni->setMaxLength(5);
371 $ni->setRequired(true);
372 $form->addItem($ni);
373 }
374 }
375
377 {
378 // cloze text
379 $cloze_text = new ilTextAreaInputGUI($this->lng->txt("cloze_text"), 'cloze_text');
380 $cloze_text->setRequired(true);
381 $cloze_text->setValue($this->applyIndizesToGapText($this->object->getClozeText()));
382 $cloze_text->setInfo($this->lng->txt("close_text_hint"));
383 $cloze_text->setRows(10);
384 $cloze_text->setCols(80);
385 if (!$this->object->getSelfAssessmentEditingMode()) {
386 if ($this->object->getAdditionalContentEditingMode() == assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT) {
387 $cloze_text->setUseRte(true);
388 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
389 $cloze_text->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
390 $cloze_text->addPlugin("latex");
391 $cloze_text->addButton("latex");
392 $cloze_text->addButton("pastelatex");
393 }
394 } else {
395 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
397 $cloze_text->setUseTagsForRteOnly(false);
398 }
399 $cloze_text->setRTESupport($this->object->getId(), "qpl", "assessment");
400 $form->addItem($cloze_text);
401
402 $tpl = new ilTemplate("tpl.il_as_qpl_cloze_gap_button_code.html", true, true, "Modules/TestQuestionPool");
403
404 $button = new ilCustomInputGUI('&nbsp;', '');
405 require_once 'Services/UIComponent/SplitButton/classes/class.ilSplitButtonGUI.php';
406 require_once 'Services/UIComponent/Button/classes/class.ilJsLinkButton.php';
407 $action_button = ilSplitButtonGUI::getInstance();
408
409 $sb_text_gap = ilJsLinkButton::getInstance();
410 $sb_text_gap->setCaption('text_gap');
411 $sb_text_gap->setName('gapbutton');
412 $sb_text_gap->setId('gaptrigger_text');
413 $action_button->setDefaultButton($sb_text_gap);
414
415 $sb_sel_gap = ilJsLinkButton::getInstance();
416 $sb_sel_gap->setCaption('select_gap');
417 $sb_sel_gap->setName('gapbutton_select');
418 $sb_sel_gap->setId('gaptrigger_select');
419 $action_button->addMenuItem(new ilButtonToSplitButtonMenuItemAdapter($sb_sel_gap));
420
421 $sb_num_gap = ilJsLinkButton::getInstance();
422 $sb_num_gap->setCaption('numeric_gap');
423 $sb_num_gap->setName('gapbutton_numeric');
424 $sb_num_gap->setId('gaptrigger_numeric');
425 $action_button->addMenuItem(new ilButtonToSplitButtonMenuItemAdapter($sb_num_gap));
426
427 $tpl->setVariable('BUTTON', $action_button->render());
428 $tpl->parseCurrentBlock();
429
430 $button->setHtml($tpl->get());
431 $form->addItem($button);
432
433 // text rating
434 if (!$this->object->getSelfAssessmentEditingMode()) {
435 $textrating = new ilSelectInputGUI($this->lng->txt("text_rating"), "textgap_rating");
436 $text_options = array(
437 "ci" => $this->lng->txt("cloze_textgap_case_insensitive"),
438 "cs" => $this->lng->txt("cloze_textgap_case_sensitive"),
439 "l1" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "1"),
440 "l2" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "2"),
441 "l3" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "3"),
442 "l4" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "4"),
443 "l5" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "5")
444 );
445 $textrating->setOptions($text_options);
446 $textrating->setValue($this->object->getTextgapRating());
447 $form->addItem($textrating);
448
449 // text field length
450 $fixedTextLength = new ilNumberInputGUI($this->lng->txt("cloze_fixed_textlength"), "fixedTextLength");
451 $ftl = $this->object->getFixedTextLength();
452
453 $fixedTextLength->setValue($ftl > 0 ? $ftl : '');
454 $fixedTextLength->setMinValue(0);
455 $fixedTextLength->setSize(3);
456 $fixedTextLength->setMaxLength(6);
457 $fixedTextLength->setInfo($this->lng->txt('cloze_fixed_textlength_description'));
458 $fixedTextLength->setRequired(false);
459 $form->addItem($fixedTextLength);
460
461 // identical scoring
462 $identical_scoring = new ilCheckboxInputGUI($this->lng->txt("identical_scoring"), "identical_scoring");
463 $identical_scoring->setValue(1);
464 $identical_scoring->setChecked($this->object->getIdenticalScoring());
465 $identical_scoring->setInfo($this->lng->txt('identical_scoring_desc'));
466 $identical_scoring->setRequired(false);
467 $form->addItem($identical_scoring);
468 }
469 return $form;
470 }
471
473 {
474 if (self::OLD_CLOZE_TEST_UI) {
475 for ($gapCounter = 0; $gapCounter < $this->object->getGapCount(); $gapCounter++) {
476 $this->populateGapFormPart($form, $gapCounter);
477 }
478 return $form;
479 } else {
480 require_once 'Modules/TestQuestionPool/classes/Form/class.ilClozeGapInputBuilderGUI.php';
481 $json = $this->populateJSON();
482 $assClozeGapCombinationObject = new assClozeGapCombination();
483 $combination_exists = $assClozeGapCombinationObject->combinationExistsForQid($this->object->id);
484 if ($combination_exists) {
485 $combinations = $assClozeGapCombinationObject->loadFromDb($this->object->id);
486 }
487 $new_builder = new ilClozeGapInputBuilderGUI();
488 $header = new ilFormSectionHeaderGUI();
489 $form->addItem($header);
490 $new_builder->setValueByArray($json);
491 $new_builder->setValueCombinationFromDb($combinations);
492 $form->addItem($new_builder);
493 return $form;
494 }
495 }
496
497 protected function populateJSON()
498 {
499 $gap = $this->object->getGaps();
500 $array = array();
501 if ($gap == null) {
502 return $array;
503 }
504 $translate_type = array('text','select','numeric');
505 $i = 0;
506 foreach ($gap as $content) {
507 $shuffle = false;
508 $value = $content->getItemsRaw();
509 $items = array();
510 for ($j = 0;$j < count($value);$j++) {
511 if ($content->getType() == 2) {
512 $items[$j] = array(
513 'answer' => $value[$j]->getAnswerText(),
514 'lower' => $value[$j]->getLowerBound(),
515 'upper' => $value[$j]->getUpperBound(),
516 'points' => $value[$j]->getPoints(),
517 'error' => false
518 );
519 } else {
520 $items[$j] = array(
521 'answer' => $value[$j]->getAnswerText(),
522 'points' => $value[$j]->getPoints(),
523 'error' => false
524 );
525
526 if ($content->getType() == 1) {
527 $shuffle = $content->getShuffle();
528 }
529 }
530 }
531 $answers[$i] = array(
532 'type' => $translate_type[$content->getType()] ,
533 'values' => $items ,
534 'shuffle' => $shuffle,
535 'text_field_length' => $content->getGapSize() > 0 ? $content->getGapSize() : '',
536 'used_in_gap_combination' => true);
537 $i++;
538 }
539 return $answers;
540 }
552 protected function populateGapFormPart($form, $gapCounter)
553 {
554 $gap = $this->object->getGap($gapCounter);
555
556 if ($gap == null) {
557 return $form;
558 }
559
560 $header = new ilFormSectionHeaderGUI();
561 $header->setTitle($this->lng->txt("gap") . " " . ($gapCounter + 1));
562 $form->addItem($header);
563
564 $gapcounter = new ilHiddenInputGUI("gap[$gapCounter]");
565 $gapcounter->setValue($gapCounter);
566 $form->addItem($gapcounter);
567
568 $gaptype = new ilSelectInputGUI($this->lng->txt('type'), "clozetype_$gapCounter");
569 $options = array(
570 0 => $this->lng->txt("text_gap"),
571 1 => $this->lng->txt("select_gap"),
572 2 => $this->lng->txt("numeric_gap")
573 );
574 $gaptype->setOptions($options);
575 $gaptype->setValue($gap->getType());
576 $form->addItem($gaptype);
577
578 if ($gap->getType() == CLOZE_TEXT) {
579 $this->populateGapSizeFormPart($form, $gap, $gapCounter);
580
581 if (count($gap->getItemsRaw()) == 0) {
582 $gap->addItem(new assAnswerCloze("", 0, 0));
583 }
584 $this->populateTextGapFormPart($form, $gap, $gapCounter);
585 } elseif ($gap->getType() == CLOZE_SELECT) {
586 if (count($gap->getItemsRaw()) == 0) {
587 $gap->addItem(new assAnswerCloze("", 0, 0));
588 }
589 $this->populateSelectGapFormPart($form, $gap, $gapCounter);
590 } elseif ($gap->getType() == CLOZE_NUMERIC) {
591 $this->populateGapSizeFormPart($form, $gap, $gapCounter);
592
593 if (count($gap->getItemsRaw()) == 0) {
594 $gap->addItem(new assAnswerCloze("", 0, 0));
595 }
596 foreach ($gap->getItemsRaw() as $item) {
597 $this->populateNumericGapFormPart($form, $item, $gapCounter);
598 }
599 }
600 return $form;
601 }
602
608 protected function populateGapSizeFormPart($form, $gap, $gapCounter)
609 {
610 $gapSizeFormItem = new ilNumberInputGUI($this->lng->txt('cloze_fixed_textlength'), "gap_" . $gapCounter . '_gapsize');
611
612 $gapSizeFormItem->allowDecimals(false);
613 $gapSizeFormItem->setMinValue(0);
614 $gapSizeFormItem->setSize(3);
615 $gapSizeFormItem->setMaxLength(6);
616 $gapSizeFormItem->setInfo($this->lng->txt('cloze_gap_size_info'));
617 $gapSizeFormItem->setValue($gap->getGapSize());
618 $form->addItem($gapSizeFormItem);
619
620 return $form;
621 }
622
635 protected function populateSelectGapFormPart($form, $gap, $gapCounter)
636 {
637 include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
638 include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
639 $values = new ilAnswerWizardInputGUI($this->lng->txt("values"), "gap_" . $gapCounter . "");
640 $values->setRequired(true);
641 $values->setQuestionObject($this->object);
642 $values->setSingleline(true);
643 $values->setAllowMove(false);
644
645 $values->setValues($gap->getItemsRaw());
646 $form->addItem($values);
647
648 // shuffle
649 $shuffle = new ilCheckboxInputGUI($this->lng->txt("shuffle_answers"), "shuffle_" . $gapCounter . "");
650 $shuffle->setValue(1);
651 $shuffle->setChecked($gap->getShuffle());
652 $shuffle->setRequired(false);
653 $form->addItem($shuffle);
654 return $form;
655 }
656
668 protected function populateTextGapFormPart($form, $gap, $gapCounter)
669 {
670 // Choices
671 include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
672 include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
673 $values = new ilAnswerWizardInputGUI($this->lng->txt("values"), "gap_" . $gapCounter . "");
674 $values->setRequired(true);
675 $values->setQuestionObject($this->object);
676 $values->setSingleline(true);
677 $values->setAllowMove(false);
678 $values->setValues($gap->getItemsRaw());
679 $form->addItem($values);
680
681 if ($this->object->getFixedTextLength() > 0) {
682 $values->setSize($this->object->getFixedTextLength());
683 $values->setMaxLength($this->object->getFixedTextLength());
684 }
685
686 return $form;
687 }
688
700 protected function populateNumericGapFormPart($form, $gap, $gapCounter)
701 {
702 // #8944: the js-based ouput in self-assessment cannot support formulas
703 if (!$this->object->getSelfAssessmentEditingMode()) {
704 $value = new ilFormulaInputGUI($this->lng->txt('value'), "gap_" . $gapCounter . "_numeric");
705 $value->setInlineStyle('text-align: right;');
706
707 $lowerbound = new ilFormulaInputGUI($this->lng->txt('range_lower_limit'), "gap_" . $gapCounter . "_numeric_lower");
708 $lowerbound->setInlineStyle('text-align: right;');
709
710 $upperbound = new ilFormulaInputGUI($this->lng->txt('range_upper_limit'), "gap_" . $gapCounter . "_numeric_upper");
711 $upperbound->setInlineStyle('text-align: right;');
712 } else {
713 $value = new ilNumberInputGUI($this->lng->txt('value'), "gap_" . $gapCounter . "_numeric");
714 $value->allowDecimals(true);
715
716 $lowerbound = new ilNumberInputGUI($this->lng->txt('range_lower_limit'), "gap_" . $gapCounter . "_numeric_lower");
717 $lowerbound->allowDecimals(true);
718
719 $upperbound = new ilNumberInputGUI($this->lng->txt('range_upper_limit'), "gap_" . $gapCounter . "_numeric_upper");
720 $upperbound->allowDecimals(true);
721 }
722
723 $value->setSize(10);
724 $value->setValue(ilUtil::prepareFormOutput($gap->getAnswertext()));
725 $value->setRequired(true);
726 $form->addItem($value);
727
728 $lowerbound->setSize(10);
729 $lowerbound->setRequired(true);
730 $lowerbound->setValue(ilUtil::prepareFormOutput($gap->getLowerBound()));
731 $form->addItem($lowerbound);
732
733 $upperbound->setSize(10);
734 $upperbound->setRequired(true);
735 $upperbound->setValue(ilUtil::prepareFormOutput($gap->getUpperBound()));
736 $form->addItem($upperbound);
737
738 if ($this->object->getFixedTextLength() > 0) {
739 $value->setSize($this->object->getFixedTextLength());
740 $value->setMaxLength($this->object->getFixedTextLength());
741 $lowerbound->setSize($this->object->getFixedTextLength());
742 $lowerbound->setMaxLength($this->object->getFixedTextLength());
743 $upperbound->setSize($this->object->getFixedTextLength());
744 $upperbound->setMaxLength($this->object->getFixedTextLength());
745 }
746
747 $points = new ilNumberInputGUI($this->lng->txt('points'), "gap_" . $gapCounter . "_numeric_points");
748 $points->allowDecimals(true);
749 $points->setSize(3);
750 $points->setRequired(true);
751 $points->setValue(ilUtil::prepareFormOutput($gap->getPoints()));
752 $form->addItem($points);
753 return $form;
754 }
755
759 public function createGaps()
760 {
761 $this->writePostData(true);
762 $this->object->saveToDb();
763 $this->editQuestion();
764 }
765
769 public function removegap()
770 {
771 $this->writePostData(true);
772 $this->object->deleteAnswerText($this->gapIndex, key($_POST['cmd']['removegap_' . $this->gapIndex]));
773 $this->editQuestion();
774 }
775
779 public function addgap()
780 {
781 $this->writePostData(true);
782 $this->object->addGapAnswer($this->gapIndex, key($_POST['cmd']['addgap_' . $this->gapIndex]) + 1, "");
783 $this->editQuestion();
784 }
785
794 public function getPreview($show_question_only = false, $showInlineFeedback = false)
795 {
796 $user_solution = is_object($this->getPreviewSession()) ? (array) $this->getPreviewSession()->getParticipantsSolution() : array();
797
798 // generate the question output
799 include_once "./Services/UICore/classes/class.ilTemplate.php";
800 $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output.html", true, true, "Modules/TestQuestionPool");
801 $output = $this->object->getClozeText();
802 foreach ($this->object->getGaps() as $gap_index => $gap) {
803 switch ($gap->getType()) {
804 case CLOZE_TEXT:
805 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_text.html", true, true, "Modules/TestQuestionPool");
806
807 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
808 if ($gap_size > 0) {
809 $gaptemplate->setCurrentBlock('size_and_maxlength');
810 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
811 $gaptemplate->parseCurrentBlock();
812 }
813 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
814 foreach ($user_solution as $val1 => $val2) {
815 if (strcmp($val1, $gap_index) == 0) {
816 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($val2) . "\"");
817 }
818 }
819 // fau: fixGapReplace - use replace function
820 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
821// fau.
822 break;
823 case CLOZE_SELECT:
824 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_select.html", true, true, "Modules/TestQuestionPool");
825 foreach ($gap->getItems($this->object->getShuffler()) as $item) {
826 $gaptemplate->setCurrentBlock("select_gap_option");
827 $gaptemplate->setVariable("SELECT_GAP_VALUE", $item->getOrder());
828 $gaptemplate->setVariable("SELECT_GAP_TEXT", ilUtil::prepareFormOutput($item->getAnswerText()));
829 foreach ($user_solution as $val1 => $val2) {
830 if (strcmp($val1, $gap_index) == 0) {
831 if (strcmp($val2, $item->getOrder()) == 0) {
832 $gaptemplate->setVariable("SELECT_GAP_SELECTED", " selected=\"selected\"");
833 }
834 }
835 }
836 $gaptemplate->parseCurrentBlock();
837 }
838 $gaptemplate->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
839 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);// fau: fixGapReplace - use replace function
840 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
841// fau.
842 break;
843 case CLOZE_NUMERIC:
844 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_numeric.html", true, true, "Modules/TestQuestionPool");
845 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
846 if ($gap_size > 0) {
847 $gaptemplate->setCurrentBlock('size_and_maxlength');
848 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
849 $gaptemplate->parseCurrentBlock();
850 }
851 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
852 foreach ($user_solution as $val1 => $val2) {
853 if (strcmp($val1, $gap_index) == 0) {
854 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($val2) . "\"");
855 }
856 }
857 // fau: fixGapReplace - use replace function
858 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
859// fau.
860 break;
861 }
862 }
863 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
864 $template->setVariable("CLOZETEXT", $this->object->prepareTextareaOutput($output, true));
865 $questionoutput = $template->get();
866 if (!$show_question_only) {
867 // get page object output
868 $questionoutput = $this->getILIASPage($questionoutput);
869 }
870 return $questionoutput;
871 }
872
879 {
880 return true;
881 }
882
898 public function getSolutionOutput(
899 $active_id,
900 $pass = null,
901 $graphicalOutput = false,
902 $result_output = false,
903 $show_question_only = true,
904 $show_feedback = false,
905 $show_correct_solution = false,
906 $show_manual_scoring = false,
907 $show_question_text = true
908 ) {
909 // get the solution of the user for the active pass or from the last pass if allowed
910 $user_solution = array();
911 if (($active_id > 0) && (!$show_correct_solution)) {
912 // get the solutions of a user
913 $user_solution = $this->object->getSolutionValues($active_id, $pass, !$this->getUseIntermediateSolution());
914 if (!is_array($user_solution)) {
915 $user_solution = array();
916 }
917 }
918
919 include_once "./Services/UICore/classes/class.ilTemplate.php";
920 $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output_solution.html", true, true, "Modules/TestQuestionPool");
921 $output = $this->object->getClozeText();
922 $assClozeGapCombinationObject = new assClozeGapCombination();
923 $check_for_gap_combinations = $assClozeGapCombinationObject->loadFromDb($this->object->getId());
924
925 foreach ($this->object->getGaps() as $gap_index => $gap) {
926 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_output_solution_gap.html", true, true, "Modules/TestQuestionPool");
927 $found = array();
928 foreach ($user_solution as $solutionarray) {
929 if ($solutionarray["value1"] == $gap_index) {
930 $found = $solutionarray;
931 }
932 }
933
934 if ($active_id) {
935 if ($graphicalOutput) {
936 // output of ok/not ok icons for user entered solutions
937 $details = $this->object->calculateReachedPoints($active_id, $pass, true, true);
938 $check = $details[$gap_index];
939
940 if (count($check_for_gap_combinations) != 0) {
941 $gaps_used_in_combination = $assClozeGapCombinationObject->getGapsWhichAreUsedInCombination($this->object->getId());
942 $custom_user_solution = array();
943 if (array_key_exists($gap_index, $gaps_used_in_combination)) {
944 $combination_id = $gaps_used_in_combination[$gap_index];
945 foreach ($gaps_used_in_combination as $key => $value) {
946 $a = 0;
947 if ($value == $combination_id) {
948 foreach ($user_solution as $solution_key => $solution_value) {
949 if ($solution_value['value1'] == $key) {
950 $result_row = array();
951 $result_row['gap_id'] = $solution_value['value1'];
952 $result_row['value'] = $solution_value['value2'];
953 array_push($custom_user_solution, $result_row);
954 }
955 }
956 }
957 }
958 $points_array = $this->object->calculateCombinationResult($custom_user_solution);
959 $max_combination_points = $assClozeGapCombinationObject->getMaxPointsForCombination($this->object->getId(), $combination_id);
960 if ($points_array[0] == $max_combination_points) {
961 $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
962 $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
963 } elseif ($points_array[0] > 0) {
964 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
965 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
966 } else {
967 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
968 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
969 }
970 } else {
971 if ($check["best"]) {
972 $gaptemplate->setCurrentBlock("icon_ok");
973 $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
974 $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
975 $gaptemplate->parseCurrentBlock();
976 } else {
977 $gaptemplate->setCurrentBlock("icon_not_ok");
978 if ($check["positive"]) {
979 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
980 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
981 } else {
982 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
983 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
984 }
985 $gaptemplate->parseCurrentBlock();
986 }
987 }
988 } else {
989 if ($check["best"]) {
990 $gaptemplate->setCurrentBlock("icon_ok");
991 $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
992 $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
993 $gaptemplate->parseCurrentBlock();
994 } else {
995 $gaptemplate->setCurrentBlock("icon_not_ok");
996 if ($check["positive"]) {
997 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
998 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
999 } else {
1000 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
1001 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
1002 }
1003 $gaptemplate->parseCurrentBlock();
1004 }
1005 }
1006 }
1007 }
1008 if ($result_output) {
1009 $points = $this->object->getMaximumGapPoints($gap_index);
1010 $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
1011 $gaptemplate->setCurrentBlock("result_output");
1012 $gaptemplate->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
1013 $gaptemplate->parseCurrentBlock();
1014 }
1015 $combination = null;
1016 switch ($gap->getType()) {
1017 case CLOZE_TEXT:
1018 $solutiontext = "";
1019 if (($active_id > 0) && (!$show_correct_solution)) {
1020 if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0)) {
1021 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++) {
1022 $solutiontext .= "&nbsp;";
1023 }
1024 } else {
1025 $solutiontext = ilUtil::prepareFormOutput($found["value2"]);
1026 }
1027 } else {
1028 $solutiontext = $this-> getBestSolutionText($gap, $gap_index, $check_for_gap_combinations);
1029 }
1030 $this->populateSolutiontextToGapTpl($gaptemplate, $gap, $solutiontext);
1031 // fau: fixGapReplace - use replace function
1032 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
1033// fau.
1034 break;
1035 case CLOZE_SELECT:
1036 $solutiontext = "";
1037 if (($active_id > 0) && (!$show_correct_solution)) {
1038 if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0)) {
1039 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++) {
1040 $solutiontext .= "&nbsp;";
1041 }
1042 } else {
1043 $item = $gap->getItem($found["value2"]);
1044 if (is_object($item)) {
1045 $solutiontext = ilUtil::prepareFormOutput($item->getAnswertext());
1046 } else {
1047 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++) {
1048 $solutiontext .= "&nbsp;";
1049 }
1050 }
1051 }
1052 } else {
1053 $solutiontext = $this-> getBestSolutionText($gap, $gap_index, $check_for_gap_combinations);
1054 }
1055 $this->populateSolutiontextToGapTpl($gaptemplate, $gap, $solutiontext);
1056 // fau: fixGapReplace - use replace function
1057 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
1058// fau.
1059 break;
1060 case CLOZE_NUMERIC:
1061 $solutiontext = "";
1062 if (($active_id > 0) && (!$show_correct_solution)) {
1063 if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0)) {
1064 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++) {
1065 $solutiontext .= "&nbsp;";
1066 }
1067 } else {
1068 $solutiontext = ilUtil::prepareFormOutput($found["value2"]);
1069 }
1070 } else {
1071 $solutiontext = $this-> getBestSolutionText($gap, $gap_index, $check_for_gap_combinations);
1072 }
1073 $this->populateSolutiontextToGapTpl($gaptemplate, $gap, $solutiontext);
1074 // fau: fixGapReplace - use replace function
1075 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
1076// fau.
1077 break;
1078 }
1079 }
1080
1081 if ($show_question_text) {
1082 $template->setVariable(
1083 "QUESTIONTEXT",
1084 $this->object->prepareTextareaOutput($this->object->getQuestion(), true)
1085 );
1086 }
1087
1088 $template->setVariable("CLOZETEXT", $this->object->prepareTextareaOutput($output, true));
1089 // generate the question output
1090 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
1091 $questionoutput = $template->get();
1092
1093 $feedback = '';
1094 if ($show_feedback) {
1095 if (!$this->isTestPresentationContext()) {
1096 $fb = $this->getGenericFeedbackOutput($active_id, $pass);
1097 $feedback .= strlen($fb) ? $fb : '';
1098 }
1099
1100 $fb = $this->getSpecificFeedbackOutput(
1101 $this->object->fetchIndexedValuesFromValuePairs($user_solution)
1102 );
1103 $feedback .= strlen($fb) ? $fb : '';
1104 }
1105 if (strlen($feedback)) {
1106 $cssClass = (
1107 $this->hasCorrectSolution($active_id, $pass) ?
1109 );
1110
1111 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
1112 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
1113 }
1114
1115 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
1116
1117 $solutionoutput = $solutiontemplate->get();
1118
1119 if (!$show_question_only) {
1120 // get page object output
1121 $solutionoutput = $this->getILIASPage($solutionoutput);
1122 }
1123
1124 return $solutionoutput;
1125 }
1126
1133 protected function getBestSolutionText($gap, $gap_index, $gap_combinations)
1134 {
1135 $combination = null;
1136 foreach ((array) $gap_combinations as $combiGapSolRow) {
1137 if ($combiGapSolRow['gap_fi'] == $gap_index && $combiGapSolRow['best_solution']) {
1138 $combination = $combiGapSolRow;
1139 break;
1140 }
1141 }
1142 $best_solution_text = ilUtil::prepareFormOutput($gap->getBestSolutionOutput(
1143 $this->object->getShuffler(),
1144 $combination
1145 ));
1146 return $best_solution_text;
1147 }
1148
1149 public function getAnswerFeedbackOutput($active_id, $pass)
1150 {
1151 include_once "./Modules/Test/classes/class.ilObjTest.php";
1152 $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
1153 if (strlen($manual_feedback)) {
1154 return $manual_feedback;
1155 }
1156 $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1157 $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1158 if (strlen($correct_feedback . $incorrect_feedback)) {
1159 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1160 $max_points = $this->object->getMaximumPoints();
1161 if ($reached_points == $max_points) {
1162 $output .= $correct_feedback;
1163 } else {
1164 $output .= $incorrect_feedback;
1165 }
1166 }
1167 $test = new ilObjTest($this->object->active_id);
1168 return $this->object->prepareTextareaOutput($output, true);
1169 }
1170
1171 public function getTestOutput(
1172 $active_id,
1173 // hey: prevPassSolutions - will be always available from now on
1174 $pass,
1175 // hey.
1176 $is_postponed = false,
1177 $use_post_solutions = false,
1178 $show_feedback = false
1179 ) {
1180 // get the solution of the user for the active pass or from the last pass if allowed
1181 $user_solution = array();
1182 if ($use_post_solutions !== false) {
1183 $indexedSolution = $this->object->fetchSolutionSubmit($use_post_solutions);
1184 $user_solution = $this->object->fetchValuePairsFromIndexedValues($indexedSolution);
1185 } elseif ($active_id) {
1186 // hey: prevPassSolutions - obsolete due to central check
1187 #include_once "./Modules/Test/classes/class.ilObjTest.php";
1188 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1189 #{
1190 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1191 #}
1192 $user_solution = $this->object->getTestOutputSolutions($active_id, $pass);
1193 // hey.
1194 if (!is_array($user_solution)) {
1195 $user_solution = array();
1196 }
1197 }
1198
1199 // generate the question output
1200 include_once "./Services/UICore/classes/class.ilTemplate.php";
1201 $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output.html", true, true, "Modules/TestQuestionPool");
1202 $output = $this->object->getClozeText();
1203 foreach ($this->object->getGaps() as $gap_index => $gap) {
1204 switch ($gap->getType()) {
1205 case CLOZE_TEXT:
1206 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_text.html", true, true, "Modules/TestQuestionPool");
1207 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
1208
1209 if ($gap_size > 0) {
1210 $gaptemplate->setCurrentBlock('size_and_maxlength');
1211 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
1212 $gaptemplate->parseCurrentBlock();
1213 }
1214
1215 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1216 foreach ($user_solution as $solution) {
1217 if (strcmp($solution["value1"], $gap_index) == 0) {
1218 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($solution["value2"]) . "\"");
1219 }
1220 }
1221 // fau: fixGapReplace - use replace function
1222 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
1223// fau.
1224 break;
1225 case CLOZE_SELECT:
1226 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_select.html", true, true, "Modules/TestQuestionPool");
1227 foreach ($gap->getItems($this->object->getShuffler()) as $item) {
1228 $gaptemplate->setCurrentBlock("select_gap_option");
1229 $gaptemplate->setVariable("SELECT_GAP_VALUE", $item->getOrder());
1230 $gaptemplate->setVariable("SELECT_GAP_TEXT", ilUtil::prepareFormOutput($item->getAnswerText()));
1231 foreach ($user_solution as $solution) {
1232 if (strcmp($solution["value1"], $gap_index) == 0) {
1233 if (strcmp($solution["value2"], $item->getOrder()) == 0) {
1234 $gaptemplate->setVariable("SELECT_GAP_SELECTED", " selected=\"selected\"");
1235 }
1236 }
1237 }
1238 $gaptemplate->parseCurrentBlock();
1239 }
1240 $gaptemplate->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
1241 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);// fau: fixGapReplace - use replace function
1242 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
1243// fau.
1244 break;
1245 case CLOZE_NUMERIC:
1246 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_numeric.html", true, true, "Modules/TestQuestionPool");
1247 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
1248 if ($gap_size > 0) {
1249 $gaptemplate->setCurrentBlock('size_and_maxlength');
1250 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
1251 $gaptemplate->parseCurrentBlock();
1252 }
1253
1254 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1255 foreach ($user_solution as $solution) {
1256 if (strcmp($solution["value1"], $gap_index) == 0) {
1257 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($solution["value2"]) . "\"");
1258 }
1259 }
1260 // fau: fixGapReplace - use replace function
1261 $output = $this->object->replaceFirstGap($output, $gaptemplate->get());
1262// fau.
1263 break;
1264 }
1265 }
1266
1267 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
1268 $template->setVariable("CLOZETEXT", $this->object->prepareTextareaOutput($output, true));
1269 $questionoutput = $template->get();
1270 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1271 return $pageoutput;
1272 }
1273
1281 public function setQuestionTabs()
1282 {
1283 global $DIC;
1284 $rbacsystem = $DIC['rbacsystem'];
1285 $ilTabs = $DIC['ilTabs'];
1286
1287 $ilTabs->clearTargets();
1288
1289 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1290 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1291 $q_type = $this->object->getQuestionType();
1292
1293 if (strlen($q_type)) {
1294 $classname = $q_type . "GUI";
1295 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1296 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1297 # $this->ctrl->setParameterByClass(strtolower($classname), 'prev_qid', $_REQUEST['prev_qid']);
1298 }
1299
1300 if ($_GET["q_id"]) {
1301 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
1302 // edit page
1303 $ilTabs->addTarget(
1304 "edit_page",
1305 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1306 array("edit", "insert", "exec_pg"),
1307 "",
1308 "",
1309 $force_active
1310 );
1311 }
1312
1313 $this->addTab_QuestionPreview($ilTabs);
1314 }
1315
1316 $force_active = false;
1317 $commands = $_POST["cmd"];
1318 if (is_array($commands)) {
1319 foreach ($commands as $key => $value) {
1320 if (preg_match("/^removegap_.*/", $key, $matches) ||
1321 preg_match("/^addgap_.*/", $key, $matches)
1322 ) {
1323 $force_active = true;
1324 }
1325 }
1326 }
1327 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
1328 $url = "";
1329 if ($classname) {
1330 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1331 }
1332 // edit question properties
1333 $ilTabs->addTarget(
1334 "edit_question",
1335 $url,
1336 array("editQuestion", "originalSyncForm", "save", "createGaps", "saveEdit"),
1337 $classname,
1338 "",
1339 $force_active
1340 );
1341 }
1342
1343 // add tab for question feedback within common class assQuestionGUI
1344 $this->addTab_QuestionFeedback($ilTabs);
1345
1346 // add tab for question hint within common class assQuestionGUI
1347 $this->addTab_QuestionHints($ilTabs);
1348
1349 // add tab for question's suggested solution within common class assQuestionGUI
1350 $this->addTab_SuggestedSolution($ilTabs, $classname);
1351
1352 // Assessment of questions sub menu entry
1353 if ($_GET["q_id"]) {
1354 $ilTabs->addTarget(
1355 "statistics",
1356 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1357 array("assessment"),
1358 $classname,
1359 ""
1360 );
1361 }
1362
1363 $this->addBackTab($ilTabs);
1364 }
1365
1366 public function getSpecificFeedbackOutput($userSolution)
1367 {
1368 if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
1369 return '';
1370 }
1371
1372 global $DIC;
1373 $lng = $DIC['lng'];
1374
1375 $feedback = '<table class="test_specific_feedback"><tbody>';
1376
1377 foreach ($this->object->gaps as $gapIndex => $gap) {
1378 $answerValue = $this->object->fetchAnswerValueForGap($userSolution, $gapIndex);
1379 $answerIndex = $this->object->feedbackOBJ->determineAnswerIndexForAnswerValue($gap, $answerValue);
1380 $fb = $this->object->feedbackOBJ->determineTestOutputGapFeedback($gapIndex, $answerIndex);
1381
1382 $caption = $lng->txt('gap') . ' ' . ($gapIndex + 1) . ': ';
1383 $feedback .= '<tr><td>';
1384 $feedback .= $caption . '</td><td>';
1385 $feedback .= $fb . '</td> </tr>';
1386 }
1387 $feedback .= '</tbody></table>';
1388
1389 return $this->object->prepareTextareaOutput($feedback, true);
1390 }
1391
1402 {
1403 return array();
1404 }
1405
1416 {
1417 return array();
1418 }
1419
1428 public function getAggregatedAnswersView($relevant_answers)
1429 {
1430 $overview = array();
1431 $aggregation = array();
1432 foreach ($relevant_answers as $answer) {
1433 $overview[$answer['active_fi']][$answer['pass']][$answer['value1']] = $answer['value2'];
1434 }
1435
1436 foreach ($overview as $active) {
1437 foreach ($active as $answer) {
1438 foreach ($answer as $option => $value) {
1439 $aggregation[$option][$value] = $aggregation[$option][$value] + 1;
1440 }
1441 }
1442 }
1443
1444 $html = '<div>';
1445 $i = 0;
1446 foreach ($this->object->getGaps() as $gap) {
1447 if ($gap->type == CLOZE_SELECT) {
1448 $html .= '<p>Gap ' . ($i + 1) . ' - SELECT</p>';
1449 $html .= '<ul>';
1450 $j = 0;
1451 foreach ($gap->getItems($this->object->getShuffler()) as $gap_item) {
1452 $aggregate = $aggregation[$i];
1453 $html .= '<li>' . $gap_item->getAnswerText() . ' - ' . ($aggregate[$j] ? $aggregate[$j] : 0) . '</li>';
1454 $j++;
1455 }
1456 $html .= '</ul>';
1457 }
1458
1459 if ($gap->type == CLOZE_TEXT) {
1460 $present_elements = array();
1461 foreach ($gap->getItems(new ilArrayElementShuffler()) as $item) {
1463 $present_elements[] = $item->getAnswertext();
1464 }
1465
1466 $html .= '<p>Gap ' . ($i + 1) . ' - TEXT</p>';
1467 $html .= '<ul>';
1468 $aggregate = (array) $aggregation[$i];
1469 foreach ($aggregate as $answer => $count) {
1470 $show_mover = '';
1471 if (in_array($answer, $present_elements)) {
1472 $show_mover = ' style="display: none;" ';
1473 }
1474
1475 $html .= '<li>' . $answer . ' - ' . $count
1476 . '&nbsp;<button class="clone_fields_add btn btn-link" ' . $show_mover . ' data-answer="' . $answer . '" name="add_gap_' . $i . '_0">
1477 <span class="sr-only"></span><span class="glyphicon glyphicon-plus"></span></button>
1478 </li>';
1479 }
1480 $html .= '</ul>';
1481 }
1482
1483 if ($gap->type == CLOZE_NUMERIC) {
1484 $html .= '<p>Gap ' . ($i + 1) . ' - NUMERIC</p>';
1485 $html .= '<ul>';
1486 $j = 0;
1487 foreach ($gap->getItems($this->object->getShuffler()) as $gap_item) {
1488 $aggregate = (array) $aggregation[$i];
1489 foreach ($aggregate as $answer => $count) {
1490 $html .= '<li>' . $answer . ' - ' . $count . '</li>';
1491 }
1492 $j++;
1493 }
1494 $html .= '</ul>';
1495 }
1496 $i++;
1497 $html .= '<hr />';
1498 }
1499
1500 $html .= '</div>';
1501 return $html;
1502 }
1503
1504 public function applyIndizesToGapText($question_text)
1505 {
1506 $parts = explode('[gap', $question_text);
1507 $i = 0;
1508 $question_text = '';
1509 foreach ($parts as $part) {
1510 if ($i == 0) {
1511 $question_text .= $part;
1512 } else {
1513 $question_text .= '[gap ' . $i . $part;
1514 }
1515 $i++;
1516 }
1517 return $question_text;
1518 }
1519
1520 public function removeIndizesFromGapText($question_text)
1521 {
1522 $parts = preg_split('/\[gap \d*\]/', $question_text);
1523 $question_text = implode('[gap]', $parts);
1524 return $question_text;
1525 }
1526
1531 private function populateSolutiontextToGapTpl($gaptemplate, $gap, $solutiontext)
1532 {
1533 if ($this->renderPurposeSupportsFormHtml() || $this->isRenderPurposePrintPdf()) {
1534 $gaptemplate->setCurrentBlock('gap_span');
1535 $gaptemplate->setVariable('SPAN_SOLUTION', $solutiontext);
1536 } elseif ($gap->getType() == CLOZE_SELECT) {
1537 $gaptemplate->setCurrentBlock('gap_select');
1538 $gaptemplate->setVariable('SELECT_SOLUTION', $solutiontext);
1539 } else {
1540 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
1541
1542 if ($gap_size > 0) {
1543 $gaptemplate->setCurrentBlock('gap_size');
1544 $gaptemplate->setVariable("GAP_SIZE", $gap_size);
1545 $gaptemplate->parseCurrentBlock();
1546 }
1547
1548 $gaptemplate->setCurrentBlock('gap_input');
1549 $gaptemplate->setVariable('INPUT_SOLUTION', $solutiontext);
1550 }
1551
1552
1553 $gaptemplate->parseCurrentBlock();
1554 }
1555
1556 protected function hasAddAnswerAction($relevantAnswers, $questionIndex)
1557 {
1558 foreach ($this->getAnswersFrequency($relevantAnswers, $questionIndex) as $answer) {
1559 if (isset($answer['actions'])) {
1560 return true;
1561 }
1562 }
1563
1564 return false;
1565 }
1566
1567 public function getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
1568 {
1569 global $DIC; /* @var ILIAS\DI\Container $DIC */
1570
1571 $table = parent::getAnswerFrequencyTableGUI(
1572 $parentGui,
1573 $parentCmd,
1574 $relevantAnswers,
1575 $questionIndex
1576 );
1577
1578 $table->setTitle(sprintf(
1579 $DIC->language()->txt('tst_corrections_answers_tbl_subindex'),
1580 $DIC->language()->txt('gap') . ' ' . ($questionIndex + 1)
1581 ));
1582
1583 if ($this->hasAddAnswerAction($relevantAnswers, $questionIndex)) {
1584 $table->addColumn('', '', '200');
1585 }
1586
1587 return $table;
1588 }
1589
1590 public function getSubQuestionsIndex()
1591 {
1592 return array_keys($this->object->getGaps());
1593 }
1594
1595 protected function getAnswerTextLabel($gapIndex, $answer)
1596 {
1597 $gap = $this->object->getGap($gapIndex);
1598
1599 switch ($gap->type) {
1600 case CLOZE_NUMERIC:
1601 case CLOZE_TEXT:
1602 return $answer;
1603
1604 case CLOZE_SELECT:
1605
1606 $items = $gap->getItems(new ilArrayElementOrderKeeper());
1607 return $items[$answer]->getAnswertext();
1608 }
1609 }
1610
1611 protected function completeAddAnswerAction($answers, $questionIndex)
1612 {
1613 $gap = $this->object->getGap($questionIndex);
1614
1615 if ($gap->type != CLOZE_TEXT) {
1616 return $answers;
1617 }
1618
1619 foreach ($answers as $key => $ans) {
1620 $found = false;
1621
1622 foreach ($gap->getItems(new ilArrayElementOrderKeeper()) as $item) {
1623 if ($ans['answer'] !== $item->getAnswerText()) {
1624 continue;
1625 }
1626
1627 $found = true;
1628 break;
1629 }
1630
1631 if (!$found) {
1632 $answers[$key]['addable'] = true;
1633 }
1634 }
1635
1636 return $answers;
1637 }
1638
1639 public function getAnswersFrequency($relevant_answers, $questionIndex)
1640 {
1641 $answers = array();
1642
1643 foreach ($relevant_answers as $row) {
1644 if ($row['value1'] != $questionIndex) {
1645 continue;
1646 }
1647
1648 if (!isset($answers[$row['value2']])) {
1649 $label = $this->getAnswerTextLabel($row['value1'], $row['value2']);
1650
1651 $answers[$row['value2']] = array(
1652 'answer' => $label, 'frequency' => 0
1653 );
1654 }
1655
1656 $answers[$row['value2']]['frequency']++;
1657 }
1658
1659 $answers = $this->completeAddAnswerAction($answers, $questionIndex);
1660
1661 return $answers;
1662 }
1663
1665 {
1666 foreach ($this->object->getGapCombinations() as $combination) {
1667 if ($combination['gap_fi'] != $gapIndex) {
1668 continue;
1669 }
1670
1671 return true;
1672 }
1673
1674 return false;
1675 }
1676
1677 protected function getGapCombinations()
1678 {
1679 $combinations = array();
1680
1681 foreach ($this->object->getGapCombinations() as $c) {
1682 if (!isset($combinations[$c['cid']])) {
1683 $combinations[$c['cid']] = array();
1684 }
1685
1686 if (!isset($combinations[$c['cid']][$c['row_id']])) {
1687 $combinations[$c['cid']][$c['row_id']] = array(
1688 'gaps' => array(), 'points' => $c['points'],
1689 );
1690 }
1691
1692 if (!isset($combinations[$c['cid']][$c['row_id']]['gaps'][$c['gap_fi']])) {
1693 $combinations[$c['cid']][$c['row_id']]['gaps'][$c['gap_fi']] = array();
1694 }
1695
1696 $combinations[$c['cid']][$c['row_id']]['gaps'][$c['gap_fi']] = $c['answer'];
1697 }
1698
1699 return $combinations;
1700 }
1701
1703 {
1704 foreach ($this->object->getGaps() as $gapIndex => $gap) {
1706 $form,
1707 $gap,
1708 $gapIndex,
1710 );
1711 }
1712
1713 if ($this->object->getGapCombinationsExists()) {
1714 foreach ($this->getGapCombinations() as $combiIndex => $gapCombination) {
1715 $this->populateGapCombinationCorrectionFormProperty($form, $gapCombination, $combiIndex);
1716 }
1717 }
1718 }
1719
1720 protected function populateGapCombinationCorrectionFormProperty(ilPropertyFormGUI $form, $gapCombi, $combiIndex)
1721 {
1722 $header = new ilFormSectionHeaderGUI();
1723 $header->setTitle("Gap Combination " . ($combiIndex + 1));
1724 $form->addItem($header);
1725
1726 require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssClozeTestCombinationVariantsInputGUI.php';
1727 $inp = new ilAssClozeTestCombinationVariantsInputGUI('Answers', 'combination_' . $combiIndex);
1728 $inp->setValues($gapCombi);
1729 $form->addItem($inp);
1730 }
1731
1737 protected function populateGapCorrectionFormProperties($form, $gap, $gapIndex, $hidePoints)
1738 {
1739 $header = new ilFormSectionHeaderGUI();
1740 $header->setTitle($this->lng->txt("gap") . " " . ($gapIndex + 1));
1741 $form->addItem($header);
1742
1743 if ($gap->getType() == CLOZE_TEXT || $gap->getType() == CLOZE_SELECT) {
1744 $this->populateTextOrSelectGapCorrectionFormProperty($form, $gap, $gapIndex, $hidePoints);
1745 } elseif ($gap->getType() == CLOZE_NUMERIC) {
1746 foreach ($gap->getItemsRaw() as $item) {
1747 $this->populateNumericGapCorrectionFormProperty($form, $item, $gapIndex, $hidePoints);
1748 }
1749 }
1750 }
1751
1752 protected function populateTextOrSelectGapCorrectionFormProperty($form, $gap, $gapIndex, $hidePoints)
1753 {
1754 require_once "Modules/TestQuestionPool/classes/forms/class.ilAssAnswerCorrectionsInputGUI.php";
1755 $values = new ilAssAnswerCorrectionsInputGUI($this->lng->txt("values"), "gap_" . $gapIndex);
1756 $values->setHidePointsEnabled($hidePoints);
1757 $values->setRequired(true);
1758 $values->setQuestionObject($this->object);
1759 $values->setValues($gap->getItemsRaw());
1760 $form->addItem($values);
1761 }
1762
1763 protected function populateNumericGapCorrectionFormProperty($form, $item, $gapIndex, $hidePoints)
1764 {
1765 $value = new ilNumberInputGUI($this->lng->txt('value'), "gap_" . $gapIndex . "_numeric");
1766 $value->allowDecimals(true);
1767 $value->setSize(10);
1768 $value->setValue(ilUtil::prepareFormOutput($item->getAnswertext()));
1769 $value->setRequired(true);
1770 $form->addItem($value);
1771
1772 $lowerbound = new ilNumberInputGUI($this->lng->txt('range_lower_limit'), "gap_" . $gapIndex . "_numeric_lower");
1773 $lowerbound->allowDecimals(true);
1774 $lowerbound->setSize(10);
1775 $lowerbound->setRequired(true);
1776 $lowerbound->setValue(ilUtil::prepareFormOutput($item->getLowerBound()));
1777 $form->addItem($lowerbound);
1778
1779 $upperbound = new ilNumberInputGUI($this->lng->txt('range_upper_limit'), "gap_" . $gapIndex . "_numeric_upper");
1780 $upperbound->allowDecimals(true);
1781 $upperbound->setSize(10);
1782 $upperbound->setRequired(true);
1783 $upperbound->setValue(ilUtil::prepareFormOutput($item->getUpperBound()));
1784 $form->addItem($upperbound);
1785
1786 if (!$hidePoints) {
1787 $points = new ilNumberInputGUI($this->lng->txt('points'), "gap_" . $gapIndex . "_numeric_points");
1788 $points->allowDecimals(true);
1789 $points->setSize(3);
1790 $points->setRequired(true);
1791 $points->setValue(ilUtil::prepareFormOutput($item->getPoints()));
1792 $form->addItem($points);
1793 }
1794 }
1795
1800 {
1801 foreach ($this->object->getGaps() as $gapIndex => $gap) {
1802 if ($this->isUsedInCombinations($gapIndex)) {
1803 continue;
1804 }
1805
1806 $this->saveGapCorrectionFormProperty($form, $gap, $gapIndex);
1807 }
1808
1809 if ($this->object->getGapCombinationsExists()) {
1811 }
1812 }
1813
1815 {
1816 if ($gap->getType() == CLOZE_TEXT || $gap->getType() == CLOZE_SELECT) {
1818 } elseif ($gap->getType() == CLOZE_NUMERIC) {
1819 foreach ($gap->getItemsRaw() as $item) {
1820 $this->saveNumericGapCorrectionFormProperty($form, $item, $gapIndex);
1821 }
1822 }
1823 }
1824
1826 {
1827 $answers = $form->getItemByPostVar('gap_' . $gapIndex)->getValues();
1828
1829 foreach ($gap->getItemsRaw() as $index => $item) {
1830 $item->setPoints((float) $answers[$index]->getPoints());
1831 }
1832 }
1833
1835 {
1836 $item->setAnswertext($form->getInput('gap_' . $gapIndex . '_numeric'));
1837 $item->setLowerBound($form->getInput('gap_' . $gapIndex . '_numeric_lower'));
1838 $item->setUpperBound($form->getInput('gap_' . $gapIndex . '_numeric_upper'));
1839 $item->setPoints($form->getInput('gap_' . $gapIndex . '_numeric_points'));
1840 }
1841
1843 {
1844 // please dont ask (!) -.-
1845
1846 $combinationPoints = array('points' => array(), 'select' => array());
1847 $combinationValues = array();
1848
1849 foreach ($this->getGapCombinations() as $combiId => $combi) {
1850 $values = $form->getItemByPostVar('combination_' . $combiId)->getValues();
1851
1852 if (!isset($combinationPoints['points'][$combiId])) {
1853 $combinationPoints['points'][$combiId] = array();
1854 $combinationPoints['select'][$combiId] = array();
1855 $combinationValues[$combiId] = array();
1856 }
1857
1858 foreach ($combi as $varId => $variant) {
1859 $combinationPoints['points'][$combiId][$varId] = (float) $values[$varId]['points'];
1860 $combinationPoints['select'][$combiId] = array_keys($values[$varId]['gaps']);
1861 $combinationValues[$combiId][$varId] = array_values($values[$varId]['gaps']);
1862 }
1863 }
1864
1865 $combinationPoints = ilUtil::stripSlashesRecursive($combinationPoints);
1866 $combinationValues = ilUtil::stripSlashesRecursive($combinationValues);
1867
1868 $assClozeGapCombinationObject = new assClozeGapCombination();
1869 $assClozeGapCombinationObject->clearGapCombinationsFromDb($this->object->getId());
1870
1871 $assClozeGapCombinationObject->saveGapCombinationToDb(
1872 $this->object->getId(),
1873 $combinationPoints,
1874 $combinationValues
1875 );
1876 }
1877}
$test
Definition: Utf8Test.php:84
$_GET["client_id"]
$_POST["username"]
setAnswertext($answertext="")
Sets the answer text.
setPoints($points=0.0)
Sets the points.
An exception for terminatinating execution or to throw for unit testing.
Class for cloze question numeric answers.
setUpperBound($bound)
Sets the upper bound.
setLowerBound($bound)
Sets the lower boind.
Class for cloze question gaps.
getType()
Gets the cloze gap type.
getItemsRaw()
Gets the items of a cloze gap.
Cloze test question GUI representation.
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
hasAddAnswerAction($relevantAnswers, $questionIndex)
applyIndizesToGapText($question_text)
populateGapCombinationCorrectionFormProperty(ilPropertyFormGUI $form, $gapCombi, $combiIndex)
populateTextOrSelectGapCorrectionFormProperty($form, $gap, $gapIndex, $hidePoints)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
populateNumericGapCorrectionFormProperty($form, $item, $gapIndex, $hidePoints)
getAnswerTextLabel($gapIndex, $answer)
getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
__construct($id=-1)
assClozeTestGUI constructor
populateSelectGapFormPart($form, $gap, $gapCounter)
Populates the form-part for a select gap.
populateNumericGapFormPart($form, $gap, $gapCounter)
Populates the form-part for a numeric gap.
createGaps()
Create gaps from cloze text.
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
$gapIndex
A temporary variable to store gap indexes of ilCtrl commands in the getCommand method.
removeIndizesFromGapText($question_text)
populateGapCorrectionFormProperties($form, $gap, $gapIndex, $hidePoints)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
Adds the question specific forms parts to a question property form gui.
populateGapSizeFormPart($form, $gap, $gapCounter)
setQuestionTabs()
Sets the ILIAS tabs for this question type.
getBestSolutionText($gap, $gap_index, $gap_combinations)
populateSolutiontextToGapTpl($gaptemplate, $gap, $solutiontext)
populateTextGapFormPart($form, $gap, $gapCounter)
Populates the form-part for a text gap.
getPreview($show_question_only=false, $showInlineFeedback=false)
Creates a preview output of the question.
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
populateGapFormPart($form, $gapCounter)
Populates a gap form-part.
addgap()
Add a gap answer.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
saveGapCombinationCorrectionFormProperties(ilPropertyFormGUI $form)
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
getAnswersFrequency($relevant_answers, $questionIndex)
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
getTestOutput( $active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
saveNumericGapCorrectionFormProperty(ilPropertyFormGUI $form, assAnswerCloze $item, $gapIndex)
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
Adds the answer specific form parts to a question property form gui.
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
completeAddAnswerAction($answers, $questionIndex)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
removegap()
Remove a gap answer.
saveGapCorrectionFormProperty(ilPropertyFormGUI $form, assClozeGap $gap, $gapIndex)
saveTextOrSelectGapCorrectionFormProperty(ilPropertyFormGUI $form, assClozeGap $gap, $gapIndex)
Class for cloze tests.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
addBackTab(ilTabsGUI $ilTabs)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
const ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT
constant for additional content editing mode "default"
This class represents a single choice wizard property in a property form.
static getSelfAssessmentTags()
Get tags allowed in question tags in self assessment mode.
This class represents a checkbox property in a property form.
This class represents a custom property in a property form.
This class represents a duration (typical hh:mm:ss) property in a property form.
This class represents a section header in a property form.
This class represents a formula text property in a property form.
This class represents a hidden form property in a property form.
This class represents a number property in a property form.
static _getUsedHTMLTags($a_module="")
Returns an array of all allowed HTML tags for text editing.
static getManualFeedback($active_id, $question_id, $pass)
Retrieves the feedback comment for a question in a test if it is finalized.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
getInput($a_post_var, $ensureValidation=true)
Returns the value of a HTTP-POST variable, identified by the passed id.
getItemByPostVar($a_post_var)
Get Item by POST variable.
This class represents a selection list property in a property form.
special template class to simplify handling of ITX/PEAR
This class represents a text area property in a property form.
This class represents a text property in a property form.
static stripSlashesRecursive($a_data, $a_strip_html=true, $a_allow="")
Strip slashes from array and sub-arrays.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
const CLOZE_NUMERIC
const CLOZE_SELECT
const CLOZE_TEXT
Cloze question constants.
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
$index
Definition: metadata.php:128
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$url
$errors
$DIC
Definition: xapitoken.php:46