ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
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
23{
24 const OLD_CLOZE_TEST_UI = false;
25
29 private $gapIndex;
30
36 public function __construct($id = -1)
37 {
38 parent::__construct();
39 include_once "./Modules/TestQuestionPool/classes/class.assClozeTest.php";
40 $this->object = new assClozeTest();
41 if ($id >= 0)
42 {
43 $this->object->loadFromDb($id);
44 }
45 }
46
47 function getCommand($cmd)
48 {
49 if (preg_match("/^(removegap|addgap)_(\d+)$/", $cmd, $matches))
50 {
51 $cmd = $matches[1];
52 $this->gapIndex = $matches[2];
53 }
54 return $cmd;
55 }
56
65 function writePostData($always = false)
66 {
67 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
68 if (!$hasErrors)
69 {
70 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
71
72 $cloze_text = $this->object->getHtmlQuestionContentPurifier()->purify($_POST['cloze_text']);
73
74 $cloze_text = $this->removeIndizesFromGapText( $cloze_text );
75 $_POST['cloze_text'] = $cloze_text;
76 $this->object->setQuestion($_POST['question']);
77
79 $this->object->setClozeText($_POST["cloze_text"]);
81 //$this->object->flushGaps();
84 return 0;
85 }
86
87 $cloze_text = $_POST['cloze_text'];
88 $cloze_text = $this->applyIndizesToGapText($cloze_text);
89 $_POST['cloze_text'] = $cloze_text;
90 return 1;
91 }
92
94 {
95 if (is_array( $_POST['gap'] ))
96 {
97 if ( $this->ctrl->getCmd() != 'createGaps' )
98 {
99 $this->object->clearGapAnswers();
100 }
101
102 foreach ($_POST['gap'] as $idx => $hidden)
103 {
104 $clozetype = $_POST['clozetype_' . $idx];
105
106 $this->object->setGapType( $idx, $clozetype );
107
108 switch($clozetype)
109 {
110 case CLOZE_TEXT:
111
112 $this->object->setGapShuffle( $idx, 0 );
113
114 if ($this->ctrl->getCmd() != 'createGaps')
115 {
116 if (is_array( $_POST['gap_' . $idx]['answer'] ))
117 {
118 foreach ($_POST['gap_' . $idx]['answer'] as $order => $value)
119 {
120 $this->object->addGapAnswer( $idx, $order, $value );
121 }
122 }
123 else
124 {
125 $this->object->addGapAnswer( $idx, 0, '' );
126 }
127 }
128
129 if (is_array( $_POST['gap_' . $idx]['points'] ))
130 {
131 foreach ($_POST['gap_' . $idx]['points'] as $order => $value)
132 {
133 $this->object->setGapAnswerPoints( $idx, $order, $value );
134 }
135 }
136
137 if (array_key_exists( 'gap_' . $idx . '_gapsize', $_POST ))
138 {
139 $this->object->setGapSize($idx, $order, $_POST['gap_' . $idx . '_gapsize'] );
140 }
141
142 break;
143
144 case CLOZE_SELECT:
145
146 $this->object->setGapShuffle( $idx, (int)(isset($_POST["shuffle_$idx"]) && $_POST["shuffle_$idx"]) );
147
148 if ($this->ctrl->getCmd() != 'createGaps')
149 {
150 if (is_array( $_POST['gap_' . $idx]['answer'] ))
151 {
152 foreach ($_POST['gap_' . $idx]['answer'] as $order => $value)
153 {
154 $this->object->addGapAnswer( $idx, $order, $value );
155 }
156 }
157 else
158 {
159 $this->object->addGapAnswer( $idx, 0, '' );
160 }
161 }
162
163 if (is_array( $_POST['gap_' . $idx]['points'] ))
164 {
165 foreach ($_POST['gap_' . $idx]['points'] as $order => $value)
166 {
167 $this->object->setGapAnswerPoints( $idx, $order, $value );
168 }
169 }
170 break;
171
172 case CLOZE_NUMERIC:
173
174 $this->object->setGapShuffle( $idx, 0 );
175
176 $gap = $this->object->getGap($idx);
177 if (!$gap) break;
178
179 $this->object->getGap($idx)->clearItems();
180
181 if (array_key_exists( 'gap_' . $idx . '_numeric', $_POST ))
182 {
183 if ($this->ctrl->getCmd() != 'createGaps')
184 {
185 $this->object->addGapAnswer(
186 $idx, 0, str_replace(",", ".", $_POST['gap_' . $idx . '_numeric'])
187 );
188 }
189
190 $this->object->setGapAnswerLowerBound(
191 $idx, 0, str_replace(",", ".", $_POST['gap_' . $idx . '_numeric_lower'])
192 );
193
194 $this->object->setGapAnswerUpperBound(
195 $idx, 0, str_replace( ",", ".", $_POST['gap_' . $idx . '_numeric_upper'])
196 );
197
198 $this->object->setGapAnswerPoints( $idx, 0, $_POST['gap_' . $idx . '_numeric_points'] );
199 }
200 else
201 {
202 if ($this->ctrl->getCmd() != 'createGaps')
203 {
204 $this->object->addGapAnswer($idx, 0, '');
205 }
206
207 $this->object->setGapAnswerLowerBound($idx, 0, '');
208
209 $this->object->setGapAnswerUpperBound($idx, 0, '');
210 }
211
212 if (array_key_exists( 'gap_' . $idx . '_gapsize', $_POST ))
213 {
214 $this->object->setGapSize($idx, $order, $_POST['gap_' . $idx . '_gapsize'] );
215 }
216 break;
217 }
218 $assClozeGapCombinationObject = new assClozeGapCombination();
219 $assClozeGapCombinationObject->clearGapCombinationsFromDb($this->object->getId());
220 if(count($_POST['gap_combination']) > 0)
221 {
222 $assClozeGapCombinationObject->saveGapCombinationToDb($this->object->getId(),ilUtil::stripSlashesRecursive($_POST['gap_combination']), ilUtil::stripSlashesRecursive($_POST['gap_combination_values']));
223 }
224 }
225 if ($this->ctrl->getCmd() != 'createGaps')
226 {
227 $this->object->updateClozeTextFromGaps();
228 }
229 }
230 }
231
233 {
234 $this->object->setClozeText( $_POST['cloze_text'] );
235 $this->object->setTextgapRating( $_POST["textgap_rating"] );
236 $this->object->setIdenticalScoring( $_POST["identical_scoring"] );
237 $this->object->setFixedTextLength( $_POST["fixedTextLength"] );
238 }
239
245 public function editQuestion($checkonly = FALSE)
246 {
247 $save = $this->isSaveCommand();
248 $this->getQuestionTemplate();
249
250 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
251 $form = new ilPropertyFormGUI();
252 $form->setFormAction($this->ctrl->getFormAction($this));
253 $form->setTitle($this->outQuestionType());
254 $form->setMultipart(FALSE);
255 $form->setTableWidth("100%");
256 $form->setId("assclozetest");
257
258 // title, author, description, question, working time (assessment mode)
259 $this->addBasicQuestionFormProperties($form);
260 $this->populateQuestionSpecificFormPart( $form );
261 $this->populateAnswerSpecificFormPart( $form );
262 $this->populateTaxonomyFormSection($form);
263
264 $this->addQuestionFormCommandButtons($form);
265
266 $errors = false;
267
268 if ($save)
269 {
270 $form->setValuesByPost();
271 $errors = !$form->checkInput();
272 $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we
273 // need this if we don't want to have duplication of backslashes
274 if ($errors) $checkonly = false;
275 }
276
277 if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
278 return $errors;
279 }
280
282 {
283 // title
284 $title = new ilTextInputGUI($this->lng->txt("title"), "title");
285 $title->setMaxLength(100);
286 $title->setValue($this->object->getTitle());
287 $title->setRequired(TRUE);
288 $form->addItem($title);
289
290 if (!$this->object->getSelfAssessmentEditingMode())
291 {
292 // author
293 $author = new ilTextInputGUI($this->lng->txt("author"), "author");
294 $author->setValue($this->object->getAuthor());
295 $author->setRequired(TRUE);
296 $form->addItem($author);
297
298 // description
299 $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
300 $description->setValue($this->object->getComment());
301 $description->setRequired(FALSE);
302 $form->addItem($description);
303 }
304 else
305 {
306 // author as hidden field
307 $hi = new ilHiddenInputGUI("author");
308 $author = ilUtil::prepareFormOutput($this->object->getAuthor());
309 if (trim($author) == "")
310 {
311 $author = "-";
312 }
313 $hi->setValue($author);
314 $form->addItem($hi);
315
316 }
317
318 // questiontext
319 $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
320 $question->setValue($this->object->prepareTextareaOutput($this->object->getQuestion()));
321 $question->setRequired(TRUE);
322 $question->setRows(10);
323 $question->setCols(80);
324 if (!$this->object->getSelfAssessmentEditingMode())
325 {
326 if( $this->object->getAdditionalContentEditingMode() == assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT )
327 {
328 $question->setUseRte(TRUE);
329 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
330 $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
331 $question->addPlugin("latex");
332 $question->addButton("latex");
333 $question->addButton("pastelatex");
334 $question->setRTESupport($this->object->getId(), "qpl", "assessment");
335 }
336 }
337 else
338 {
339 $question->setRteTags(self::getSelfAssessmentTags());
340 $question->setUseTagsForRteOnly(false);
341 }
342 $form->addItem($question);
343
344// $tpl = new ilTemplate("tpl.il_as_qpl_cloze_gap_button_code.html", TRUE, TRUE, "Modules/TestQuestionPool");
345// $tpl->setVariable('INSERT_GAP', $this->lng->txt('insert_gap'));
346// $tpl->setVariable('CREATE_GAPS', $this->lng->txt('create_gaps'));
347// $tpl->parseCurrentBlock();
348// $button = new ilCustomInputGUI('&nbsp;','');
349// $button->setHtml($tpl->get());
350// $form->addItem($button);
351
352 if (!$this->object->getSelfAssessmentEditingMode())
353 {
354 // duration
355 $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
356 $duration->setShowHours(TRUE);
357 $duration->setShowMinutes(TRUE);
358 $duration->setShowSeconds(TRUE);
359 $ewt = $this->object->getEstimatedWorkingTime();
360 $duration->setHours($ewt["h"]);
361 $duration->setMinutes($ewt["m"]);
362 $duration->setSeconds($ewt["s"]);
363 $duration->setRequired(FALSE);
364 $form->addItem($duration);
365 }
366 else
367 {
368 // number of tries
369 if (strlen($this->object->getNrOfTries()))
370 {
371 $nr_tries = $this->object->getNrOfTries();
372 }
373 else
374 {
375 $nr_tries = $this->object->getDefaultNrOfTries();
376 }
377 /*if ($nr_tries <= 0)
378 {
379 $nr_tries = 1;
380 }*/
381
382 if ($nr_tries < 0)
383 {
384 $nr_tries = 0;
385 }
386
387 $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
388 $ni->setValue($nr_tries);
389 //$ni->setMinValue(1);
390 $ni->setMinValue(0);
391 $ni->setSize(5);
392 $ni->setMaxLength(5);
393 $ni->setRequired(true);
394 $form->addItem($ni);
395 }
396 }
397
399 {
400 // cloze text
401 $cloze_text = new ilTextAreaInputGUI($this->lng->txt("cloze_text"), 'cloze_text');
402 $cloze_text->setRequired(true);
403 $cloze_text->setValue($this->applyIndizesToGapText($this->object->getClozeText()));
404 $cloze_text->setInfo($this->lng->txt("close_text_hint"));
405 $cloze_text->setRows( 10 );
406 $cloze_text->setCols( 80 );
407 if (!$this->object->getSelfAssessmentEditingMode())
408 {
409 if( $this->object->getAdditionalContentEditingMode() == assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT )
410 {
411 $cloze_text->setUseRte(TRUE);
412 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
413 $cloze_text->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
414 $cloze_text->addPlugin("latex");
415 $cloze_text->addButton("latex");
416 $cloze_text->addButton("pastelatex");
417 }
418 }
419 else
420 {
421 $cloze_text->setRteTags(self::getSelfAssessmentTags());
422 $cloze_text->setUseTagsForRteOnly(false);
423 }
424 $cloze_text->setRTESupport($this->object->getId(), "qpl", "assessment");
425 $form->addItem($cloze_text);
426
427 $tpl = new ilTemplate("tpl.il_as_qpl_cloze_gap_button_code.html", TRUE, TRUE, "Modules/TestQuestionPool");
428 $tpl->setVariable('INSERT_GAP', $this->lng->txt('insert_gap'));
429 $tpl->setVariable('CREATE_GAPS', $this->lng->txt('create_gaps'));
430 $tpl->parseCurrentBlock();
431 $button = new ilCustomInputGUI('&nbsp;','');
432 $button->setHtml($tpl->get());
433 $form->addItem($button);
434
435 // text rating
436 if (!$this->object->getSelfAssessmentEditingMode())
437 {
438 $textrating = new ilSelectInputGUI($this->lng->txt( "text_rating" ), "textgap_rating");
439 $text_options = array(
440 "ci" => $this->lng->txt( "cloze_textgap_case_insensitive" ),
441 "cs" => $this->lng->txt( "cloze_textgap_case_sensitive" ),
442 "l1" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "1" ),
443 "l2" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "2" ),
444 "l3" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "3" ),
445 "l4" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "4" ),
446 "l5" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "5" )
447 );
448 $textrating->setOptions( $text_options );
449 $textrating->setValue( $this->object->getTextgapRating() );
450 $form->addItem( $textrating );
451
452 // text field length
453 $fixedTextLength = new ilNumberInputGUI($this->lng->txt( "cloze_fixed_textlength" ), "fixedTextLength");
454 $ftl = $this->object->getFixedTextLength();
455
456 $fixedTextLength->setValue( $ftl > 0 ? $ftl : '' );
457 $fixedTextLength->setMinValue( 0 );
458 $fixedTextLength->setSize( 3 );
459 $fixedTextLength->setMaxLength( 6 );
460 $fixedTextLength->setInfo( $this->lng->txt( 'cloze_fixed_textlength_description' ) );
461 $fixedTextLength->setRequired( false );
462 $form->addItem( $fixedTextLength );
463
464 // identical scoring
465 $identical_scoring = new ilCheckboxInputGUI($this->lng->txt( "identical_scoring" ), "identical_scoring");
466 $identical_scoring->setValue( 1 );
467 $identical_scoring->setChecked( $this->object->getIdenticalScoring() );
468 $identical_scoring->setInfo( $this->lng->txt( 'identical_scoring_desc' ) );
469 $identical_scoring->setRequired( FALSE );
470 $form->addItem( $identical_scoring );
471 }
472 return $form;
473 }
474
476 {
477 if(self::OLD_CLOZE_TEST_UI)
478 {
479 for ($gapCounter = 0; $gapCounter < $this->object->getGapCount(); $gapCounter++)
480 {
481 $this->populateGapFormPart( $form, $gapCounter );
482 }
483 return $form;
484 }
485 else
486 {
487 require_once 'Modules/TestQuestionPool/classes/Form/class.ilClozeGapInputBuilderGUI.php';
488 $json=$this->populateJSON();
489 $assClozeGapCombinationObject = new assClozeGapCombination();
490 $combination_exists = $assClozeGapCombinationObject->combinationExistsForQid($this->object->id);
491 if($combination_exists)
492 {
493 $combinations = $assClozeGapCombinationObject->loadFromDb($this->object->id);
494 }
495 $new_builder = new ilClozeGapInputBuilderGUI();
496 $header = new ilFormSectionHeaderGUI();
497 $form->addItem($header);
498 $new_builder->setValueByArray($json);
499 $new_builder->setValueCombinationFromDb($combinations);
500 $form->addItem($new_builder);
501 return $form;
502 }
503 }
504
505 protected function populateJSON()
506 {
507 $gap = $this->object->getGaps();
508 $array = array();
509 if ($gap == null)
510 {
511 return $array;
512 }
513 $translate_type=array('text','select','numeric');
514 $i = 0;
515 foreach ($gap as $content)
516 {
517 $shuffle=false;
518 $value=$content->getItemsRaw();
519 $items=array();
520 for($j=0;$j<count($value);$j++)
521 {
522 if($content->getType()==2)
523 {
524 $items[$j] = array(
525 'answer' => $value[$j]->getAnswerText(),
526 'lower' => $value[$j]->getLowerBound(),
527 'upper' => $value[$j]->getUpperBound(),
528 'points' => $value[$j]->getPoints(),
529 'error' => false
530 );
531 }
532 else
533 {
534 $items[$j] = array(
535 'answer' => $value[$j]->getAnswerText(),
536 'points' => $value[$j]->getPoints(),
537 'error' => false
538 );
539
540 if($content->getType()==1)
541 {
542 $shuffle=$content->getShuffle();
543 }
544 }
545 }
546 $answers[$i]=array(
547 'type' => $translate_type[$content->getType()] ,
548 'values' => $items ,
549 'shuffle' => $shuffle,
550 'text_field_length' => $content->getGapSize() > 0 ? $content->getGapSize() : '',
551 'used_in_gap_combination' => true);
552 $i++;
553 }
554 return $answers;
555 }
567 protected function populateGapFormPart($form, $gapCounter)
568 {
569 $gap = $this->object->getGap( $gapCounter );
570
571 if ($gap == null)
572 {
573 return $form;
574 }
575
576 $header = new ilFormSectionHeaderGUI();
577 $header->setTitle( $this->lng->txt( "gap" ) . " " . ($gapCounter + 1) );
578 $form->addItem( $header );
579
580 $gapcounter = new ilHiddenInputGUI("gap[$gapCounter]");
581 $gapcounter->setValue( $gapCounter );
582 $form->addItem( $gapcounter );
583
584 $gaptype = new ilSelectInputGUI($this->lng->txt( 'type' ), "clozetype_$gapCounter");
585 $options = array(
586 0 => $this->lng->txt( "text_gap" ),
587 1 => $this->lng->txt( "select_gap" ),
588 2 => $this->lng->txt( "numeric_gap" )
589 );
590 $gaptype->setOptions( $options );
591 $gaptype->setValue( $gap->getType() );
592 $form->addItem( $gaptype );
593
594 if ($gap->getType() == CLOZE_TEXT)
595 {
596 $this->populateGapSizeFormPart($form, $gap, $gapCounter);
597
598 if (count( $gap->getItemsRaw() ) == 0)
599 $gap->addItem( new assAnswerCloze("", 0, 0) );
600 $this->populateTextGapFormPart( $form, $gap, $gapCounter );
601 }
602 else if ($gap->getType() == CLOZE_SELECT)
603 {
604 if (count( $gap->getItemsRaw() ) == 0)
605 $gap->addItem( new assAnswerCloze("", 0, 0) );
606 $this->populateSelectGapFormPart( $form, $gap, $gapCounter );
607 }
608 else if ($gap->getType() == CLOZE_NUMERIC)
609 {
610 $this->populateGapSizeFormPart($form, $gap, $gapCounter);
611
612 if (count( $gap->getItemsRaw() ) == 0)
613 $gap->addItem( new assAnswerCloze("", 0, 0) );
614 foreach ($gap->getItemsRaw() as $item)
615 {
616 $this->populateNumericGapFormPart( $form, $item, $gapCounter );
617 }
618 }
619 return $form;
620 }
621
627 protected function populateGapSizeFormPart($form, $gap, $gapCounter)
628 {
629 $gapSizeFormItem = new ilNumberInputGUI($this->lng->txt('cloze_fixed_textlength'), "gap_".$gapCounter.'_gapsize');
630
631 $gapSizeFormItem->allowDecimals(false);
632 $gapSizeFormItem->setMinValue(0);
633 $gapSizeFormItem->setSize( 3 );
634 $gapSizeFormItem->setMaxLength( 6 );
635 $gapSizeFormItem->setInfo($this->lng->txt('cloze_gap_size_info'));
636 $gapSizeFormItem->setValue($gap->getGapSize());
637 $form->addItem($gapSizeFormItem);
638
639 return $form;
640 }
641
654 protected function populateSelectGapFormPart($form, $gap, $gapCounter)
655 {
656 include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
657 include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
658 $values = new ilAnswerWizardInputGUI($this->lng->txt( "values" ), "gap_" . $gapCounter . "");
659 $values->setRequired( true );
660 $values->setQuestionObject( $this->object );
661 $values->setSingleline( true );
662 $values->setAllowMove( false );
663
664 $values->setValues( $gap->getItemsRaw() );
665 $form->addItem( $values );
666
667 // shuffle
668 $shuffle = new ilCheckboxInputGUI($this->lng->txt( "shuffle_answers" ), "shuffle_" . $gapCounter . "");
669 $shuffle->setValue( 1 );
670 $shuffle->setChecked( $gap->getShuffle() );
671 $shuffle->setRequired( FALSE );
672 $form->addItem( $shuffle );
673 return $form;
674 }
675
687 protected function populateTextGapFormPart($form, $gap, $gapCounter)
688 {
689 // Choices
690 include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
691 include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
692 $values = new ilAnswerWizardInputGUI($this->lng->txt( "values" ), "gap_" . $gapCounter . "");
693 $values->setRequired( true );
694 $values->setQuestionObject( $this->object );
695 $values->setSingleline( true );
696 $values->setAllowMove( false );
697 $values->setValues( $gap->getItemsRaw() );
698 $form->addItem( $values );
699
700 if( $this->object->getFixedTextLength() > 0 )
701 {
702 $values->setSize( $this->object->getFixedTextLength() );
703 $values->setMaxLength( $this->object->getFixedTextLength() );
704 }
705
706 return $form;
707 }
708
720 protected function populateNumericGapFormPart($form, $gap, $gapCounter)
721 {
722 // #8944: the js-based ouput in self-assessment cannot support formulas
723 if (!$this->object->getSelfAssessmentEditingMode())
724 {
725 $value = new ilFormulaInputGUI($this->lng->txt( 'value' ), "gap_" . $gapCounter . "_numeric");
726 $value->setInlineStyle( 'text-align: right;' );
727
728 $lowerbound = new ilFormulaInputGUI($this->lng->txt( 'range_lower_limit'), "gap_" . $gapCounter . "_numeric_lower");
729 $lowerbound->setInlineStyle( 'text-align: right;' );
730
731 $upperbound = new ilFormulaInputGUI($this->lng->txt( 'range_upper_limit'), "gap_" . $gapCounter . "_numeric_upper");
732 $upperbound->setInlineStyle( 'text-align: right;' );
733 }
734 else
735 {
736 $value = new ilNumberInputGUI($this->lng->txt( 'value' ), "gap_" . $gapCounter . "_numeric");
737 $value->allowDecimals( true );
738
739 $lowerbound = new ilNumberInputGUI($this->lng->txt( 'range_lower_limit'), "gap_" . $gapCounter . "_numeric_lower");
740 $lowerbound->allowDecimals( true );
741
742 $upperbound = new ilNumberInputGUI($this->lng->txt( 'range_upper_limit'), "gap_" . $gapCounter . "_numeric_upper");
743 $upperbound->allowDecimals( true );
744 }
745
746 $value->setSize( 10 );
747 $value->setValue( ilUtil::prepareFormOutput( $gap->getAnswertext() ) );
748 $value->setRequired( true );
749 $form->addItem( $value );
750
751 $lowerbound->setSize( 10 );
752 $lowerbound->setRequired( true );
753 $lowerbound->setValue( ilUtil::prepareFormOutput( $gap->getLowerBound() ) );
754 $form->addItem( $lowerbound );
755
756 $upperbound->setSize( 10 );
757 $upperbound->setRequired( true );
758 $upperbound->setValue( ilUtil::prepareFormOutput( $gap->getUpperBound() ) );
759 $form->addItem( $upperbound );
760
761 if( $this->object->getFixedTextLength() > 0 )
762 {
763 $value->setSize( $this->object->getFixedTextLength() );
764 $value->setMaxLength( $this->object->getFixedTextLength() );
765 $lowerbound->setSize( $this->object->getFixedTextLength() );
766 $lowerbound->setMaxLength( $this->object->getFixedTextLength() );
767 $upperbound->setSize( $this->object->getFixedTextLength() );
768 $upperbound->setMaxLength( $this->object->getFixedTextLength() );
769 }
770
771 $points = new ilNumberInputGUI($this->lng->txt( 'points' ), "gap_" . $gapCounter . "_numeric_points");
772 $points->allowDecimals(true);
773 $points->setSize( 3 );
774 $points->setRequired( true );
775 $points->setValue( ilUtil::prepareFormOutput( $gap->getPoints() ) );
776 $form->addItem( $points );
777 return $form;
778 }
779
783 public function createGaps()
784 {
785 $this->writePostData(true);
786 $this->object->saveToDb();
787 $this->editQuestion();
788 }
789
793 function removegap()
794 {
795 $this->writePostData(true);
796 $this->object->deleteAnswerText($this->gapIndex, key($_POST['cmd']['removegap_' . $this->gapIndex]));
797 $this->editQuestion();
798 }
799
803 function addgap()
804 {
805 $this->writePostData(true);
806 $this->object->addGapAnswer($this->gapIndex, key($_POST['cmd']['addgap_' . $this->gapIndex])+1, "");
807 $this->editQuestion();
808 }
809
818 function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
819 {
820 $user_solution = is_object($this->getPreviewSession()) ? (array)$this->getPreviewSession()->getParticipantsSolution() : array();
821
822 // generate the question output
823 include_once "./Services/UICore/classes/class.ilTemplate.php";
824 $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
825 $output = $this->object->getClozeText();
826 foreach ($this->object->getGaps() as $gap_index => $gap)
827 {
828 switch ($gap->getType())
829 {
830 case CLOZE_TEXT:
831 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_text.html", TRUE, TRUE, "Modules/TestQuestionPool");
832
833 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
834 if($gap_size > 0)
835 {
836 $gaptemplate->setCurrentBlock('size_and_maxlength');
837 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
838 $gaptemplate->parseCurrentBlock();
839 }
840 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
841 foreach ($user_solution as $val1 => $val2)
842 {
843 if (strcmp($val1, $gap_index) == 0)
844 {
845 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($val2) . "\"");
846 }
847 }
848 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
849 break;
850 case CLOZE_SELECT:
851 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_select.html", TRUE, TRUE, "Modules/TestQuestionPool");
852 foreach ($gap->getItems() as $item)
853 {
854 $gaptemplate->setCurrentBlock("select_gap_option");
855 $gaptemplate->setVariable("SELECT_GAP_VALUE", $item->getOrder());
856 $gaptemplate->setVariable("SELECT_GAP_TEXT", ilUtil::prepareFormOutput($item->getAnswerText()));
857 foreach ($user_solution as $val1 => $val2)
858 {
859 if (strcmp($val1, $gap_index) == 0)
860 {
861 if (strcmp($val2, $item->getOrder()) == 0)
862 {
863 $gaptemplate->setVariable("SELECT_GAP_SELECTED", " selected=\"selected\"");
864 }
865 }
866 }
867 $gaptemplate->parseCurrentBlock();
868 }
869 $gaptemplate->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
870 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
871 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
872 break;
873 case CLOZE_NUMERIC:
874 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_numeric.html", TRUE, TRUE, "Modules/TestQuestionPool");
875 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
876 if($gap_size > 0)
877 {
878 $gaptemplate->setCurrentBlock('size_and_maxlength');
879 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
880 $gaptemplate->parseCurrentBlock();
881 }
882 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
883 foreach ($user_solution as $val1 => $val2)
884 {
885 if (strcmp($val1, $gap_index) == 0)
886 {
887 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($val2) . "\"");
888 }
889 }
890 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
891 break;
892 }
893 }
894 $template->setVariable("QUESTIONTEXT",$this->object->prepareTextareaOutput( $this->object->getQuestion(), true));
895 $template->setVariable("CLOZETEXT", $this->object->prepareTextareaOutput($output, TRUE));
896 $questionoutput = $template->get();
897 if (!$show_question_only)
898 {
899 // get page object output
900 $questionoutput = $this->getILIASPage($questionoutput);
901 }
902 return $questionoutput;
903 }
904
921 $active_id,
922 $pass = NULL,
923 $graphicalOutput = FALSE,
924 $result_output = FALSE,
925 $show_question_only = TRUE,
926 $show_feedback = FALSE,
927 $show_correct_solution = FALSE,
928 $show_manual_scoring = FALSE,
929 $show_question_text = TRUE
930 )
931 {
932 // get the solution of the user for the active pass or from the last pass if allowed
933 $user_solution = array();
934 if (($active_id > 0) && (!$show_correct_solution))
935 {
936 // get the solutions of a user
937 $user_solution =& $this->object->getSolutionValues($active_id, $pass);
938 if(!is_array($user_solution))
939 {
940 $user_solution = array();
941 }
942 }
943
944 include_once "./Services/UICore/classes/class.ilTemplate.php";
945 $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
946 $output = $this->object->getClozeText();
947 foreach ($this->object->getGaps() as $gap_index => $gap)
948 {
949 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_output_solution_gap.html", TRUE, TRUE, "Modules/TestQuestionPool");
950 $found = array();
951 foreach ($user_solution as $solutionarray)
952 {
953 if ($solutionarray["value1"] == $gap_index) $found = $solutionarray;
954 }
955
956 if ($active_id)
957 {
958 if ($graphicalOutput)
959 {
960 // output of ok/not ok icons for user entered solutions
961 $details = $this->object->calculateReachedPoints($active_id, $pass, TRUE);
962 $check = $details[$gap_index];
963
964 $assClozeGapCombinationObject = new assClozeGapCombination();
965 $check_for_gap_combinations = $assClozeGapCombinationObject->loadFromDb($this->object->getId());
966 if(count($check_for_gap_combinations) != 0)
967 {
968 $gaps_used_in_combination = $assClozeGapCombinationObject->getGapsWhichAreUsedInCombination($this->object->getId());
969 $custom_user_solution = array();
970 if(array_key_exists($gap_index, $gaps_used_in_combination))
971 {
972 $combination_id = $gaps_used_in_combination[$gap_index];
973 foreach($gaps_used_in_combination as $key => $value)
974 {
975 $a = 0;
976 if($value == $combination_id)
977 {
978
979 foreach($user_solution as $solution_key => $solution_value)
980 {
981 if($solution_value['value1'] == $key)
982 {
983 $result_row = array();
984 $result_row['gap_id'] = $solution_value['value1'];
985 $result_row['value'] = $solution_value['value2'];
986 array_push($custom_user_solution, $result_row);
987 }
988 }
989 }
990 }
991 $points_array = $this->object->calculateCombinationResult($custom_user_solution);
992 $max_combination_points = $assClozeGapCombinationObject->getMaxPointsForCombination($this->object->getId(), $combination_id);
993 if($points_array[0] == $max_combination_points)
994 {
995 $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
996 $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
997 }
998 else if($points_array[0] > 0)
999 {
1000 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
1001 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
1002 }
1003 else
1004 {
1005 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
1006 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
1007 }
1008
1009 }
1010 else
1011 {
1012 if ($check["best"])
1013 {
1014 $gaptemplate->setCurrentBlock("icon_ok");
1015 $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
1016 $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
1017 $gaptemplate->parseCurrentBlock();
1018 }
1019 else
1020 {
1021 $gaptemplate->setCurrentBlock("icon_not_ok");
1022 if ($check["positive"])
1023 {
1024 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
1025 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
1026 }
1027 else
1028 {
1029 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
1030 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
1031 }
1032 $gaptemplate->parseCurrentBlock();
1033 }
1034 }
1035 }
1036 else
1037 {
1038 if ($check["best"])
1039 {
1040 $gaptemplate->setCurrentBlock("icon_ok");
1041 $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
1042 $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
1043 $gaptemplate->parseCurrentBlock();
1044 }
1045 else
1046 {
1047 $gaptemplate->setCurrentBlock("icon_not_ok");
1048 if ($check["positive"])
1049 {
1050 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
1051 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
1052 }
1053 else
1054 {
1055 $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
1056 $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
1057 }
1058 $gaptemplate->parseCurrentBlock();
1059 }
1060 }
1061
1062 }
1063 }
1064 if ($result_output)
1065 {
1066 $points = $this->object->getMaximumGapPoints($gap_index);
1067 $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
1068 $gaptemplate->setCurrentBlock("result_output");
1069 $gaptemplate->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
1070 $gaptemplate->parseCurrentBlock();
1071 }
1072 switch ($gap->getType())
1073 {
1074 case CLOZE_TEXT:
1075 $solutiontext = "";
1076 if (($active_id > 0) && (!$show_correct_solution))
1077 {
1078 if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0))
1079 {
1080 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
1081 {
1082 $solutiontext .= "&nbsp;";
1083 }
1084 }
1085 else
1086 {
1087 $solutiontext = ilUtil::prepareFormOutput($found["value2"]);
1088 }
1089 }
1090 else
1091 {
1092 $solutiontext = ilUtil::prepareFormOutput($gap->getBestSolutionOutput());
1093 }
1094 $gaptemplate->setVariable("SOLUTION", $solutiontext);
1095 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1096 break;
1097 case CLOZE_SELECT:
1098 $solutiontext = "";
1099 if (($active_id > 0) && (!$show_correct_solution))
1100 {
1101 if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0))
1102 {
1103 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
1104 {
1105 $solutiontext .= "&nbsp;";
1106 }
1107 }
1108 else
1109 {
1110 $item = $gap->getItem($found["value2"]);
1111 if (is_object($item))
1112 {
1113 $solutiontext = ilUtil::prepareFormOutput($item->getAnswertext());
1114 }
1115 else
1116 {
1117 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
1118 {
1119 $solutiontext .= "&nbsp;";
1120 }
1121 }
1122 }
1123 }
1124 else
1125 {
1126 $solutiontext = ilUtil::prepareFormOutput($gap->getBestSolutionOutput());
1127 }
1128 $gaptemplate->setVariable("SOLUTION", $solutiontext);
1129 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1130 break;
1131 case CLOZE_NUMERIC:
1132 $solutiontext = "";
1133 if (($active_id > 0) && (!$show_correct_solution))
1134 {
1135 if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0))
1136 {
1137 for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
1138 {
1139 $solutiontext .= "&nbsp;";
1140 }
1141 }
1142 else
1143 {
1144 $solutiontext = ilUtil::prepareFormOutput($found["value2"]);
1145 }
1146 }
1147 else
1148 {
1149 $solutiontext = ilUtil::prepareFormOutput($gap->getBestSolutionOutput());
1150 }
1151 $gaptemplate->setVariable("SOLUTION", $solutiontext);
1152 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1153 break;
1154 }
1155 }
1156
1157 if ($show_question_text)
1158 {
1159 $template->setVariable(
1160 "QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true)
1161 );
1162 }
1163
1164 $template->setVariable("CLOZETEXT", $this->object->prepareTextareaOutput($output, TRUE));
1165 // generate the question output
1166 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
1167 $questionoutput = $template->get();
1168
1169 $feedback = '';
1170 if($show_feedback)
1171 {
1172 $fb = $this->getGenericFeedbackOutput($active_id, $pass);
1173 $feedback .= strlen($fb) ? $fb : '';
1174
1175 $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
1176 $feedback .= strlen($fb) ? $fb : '';
1177 }
1178 if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $feedback);
1179
1180 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
1181
1182 $solutionoutput = $solutiontemplate->get();
1183
1184 if (!$show_question_only)
1185 {
1186 // get page object output
1187 $solutionoutput = $this->getILIASPage($solutionoutput);
1188 }
1189
1190 return $solutionoutput;
1191 }
1192
1193 public function getAnswerFeedbackOutput($active_id, $pass)
1194 {
1195 include_once "./Modules/Test/classes/class.ilObjTest.php";
1196 $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
1197 if (strlen($manual_feedback))
1198 {
1199 return $manual_feedback;
1200 }
1201 $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1202 $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1203 if (strlen($correct_feedback.$incorrect_feedback))
1204 {
1205 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1206 $max_points = $this->object->getMaximumPoints();
1207 if ($reached_points == $max_points)
1208 {
1209 $output .= $correct_feedback;
1210 }
1211 else
1212 {
1213 $output .= $incorrect_feedback;
1214 }
1215 }
1216 $test = new ilObjTest($this->object->active_id);
1217 return $this->object->prepareTextareaOutput($output, TRUE);
1218 }
1219
1221 $active_id,
1222 $pass = NULL,
1223 $is_postponed = FALSE,
1224 $use_post_solutions = FALSE,
1225 $show_feedback = FALSE
1226 )
1227 {
1228 // get the solution of the user for the active pass or from the last pass if allowed
1229 $user_solution = array();
1230 if ($active_id)
1231 {
1232 include_once "./Modules/Test/classes/class.ilObjTest.php";
1233 if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1234 {
1235 if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1236 }
1237 $user_solution =& $this->object->getSolutionValues($active_id, $pass);
1238 if (!is_array($user_solution))
1239 {
1240 $user_solution = array();
1241 }
1242 }
1243
1244 // generate the question output
1245 include_once "./Services/UICore/classes/class.ilTemplate.php";
1246 $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
1247 $output = $this->object->getClozeText();
1248 foreach ($this->object->getGaps() as $gap_index => $gap)
1249 {
1250 switch ($gap->getType())
1251 {
1252 case CLOZE_TEXT:
1253 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_text.html", TRUE, TRUE, "Modules/TestQuestionPool");
1254 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
1255
1256 if($gap_size > 0)
1257 {
1258 $gaptemplate->setCurrentBlock('size_and_maxlength');
1259 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
1260 $gaptemplate->parseCurrentBlock();
1261 }
1262
1263 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1264 foreach ($user_solution as $solution)
1265 {
1266 if (strcmp($solution["value1"], $gap_index) == 0)
1267 {
1268 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($solution["value2"]) . "\"");
1269 }
1270 }
1271 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1272 break;
1273 case CLOZE_SELECT:
1274 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_select.html", TRUE, TRUE, "Modules/TestQuestionPool");
1275 foreach ($gap->getItems() as $item)
1276 {
1277 $gaptemplate->setCurrentBlock("select_gap_option");
1278 $gaptemplate->setVariable("SELECT_GAP_VALUE", $item->getOrder());
1279 $gaptemplate->setVariable("SELECT_GAP_TEXT", ilUtil::prepareFormOutput($item->getAnswerText()));
1280 foreach ($user_solution as $solution)
1281 {
1282 if (strcmp($solution["value1"], $gap_index) == 0)
1283 {
1284 if (strcmp($solution["value2"], $item->getOrder()) == 0)
1285 {
1286 $gaptemplate->setVariable("SELECT_GAP_SELECTED", " selected=\"selected\"");
1287 }
1288 }
1289 }
1290 $gaptemplate->parseCurrentBlock();
1291 }
1292 $gaptemplate->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
1293 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1294 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1295 break;
1296 case CLOZE_NUMERIC:
1297 $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_numeric.html", TRUE, TRUE, "Modules/TestQuestionPool");
1298 $gap_size = $gap->getGapSize() > 0 ? $gap->getGapSize() : $this->object->getFixedTextLength();
1299 if($gap_size > 0)
1300 {
1301 $gaptemplate->setCurrentBlock('size_and_maxlength');
1302 $gaptemplate->setVariable("TEXT_GAP_SIZE", $gap_size);
1303 $gaptemplate->parseCurrentBlock();
1304 }
1305
1306 $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1307 foreach ($user_solution as $solution)
1308 {
1309 if (strcmp($solution["value1"], $gap_index) == 0)
1310 {
1311 $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($solution["value2"]) . "\"");
1312 }
1313 }
1314 $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1315 break;
1316 }
1317 }
1318
1319 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), true));
1320 $template->setVariable("CLOZETEXT", $this->object->prepareTextareaOutput($output, TRUE));
1321 $questionoutput = $template->get();
1322 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1323 return $pageoutput;
1324 }
1325
1333 public function setQuestionTabs()
1334 {
1335 global $rbacsystem, $ilTabs;
1336
1337 $ilTabs->clearTargets();
1338
1339 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1340 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1341 $q_type = $this->object->getQuestionType();
1342
1343 if (strlen($q_type))
1344 {
1345 $classname = $q_type . "GUI";
1346 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1347 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1348# $this->ctrl->setParameterByClass(strtolower($classname), 'prev_qid', $_REQUEST['prev_qid']);
1349 }
1350
1351 if ($_GET["q_id"])
1352 {
1353 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1354 {
1355 // edit page
1356 $ilTabs->addTarget("edit_page",
1357 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1358 array("edit", "insert", "exec_pg"),
1359 "", "", $force_active);
1360 }
1361
1362 $this->addTab_QuestionPreview($ilTabs);
1363 }
1364
1365 $force_active = false;
1366 $commands = $_POST["cmd"];
1367 if (is_array($commands))
1368 {
1369 foreach ($commands as $key => $value)
1370 {
1371 if (preg_match("/^removegap_.*/", $key, $matches) ||
1372 preg_match("/^addgap_.*/", $key, $matches)
1373 )
1374 {
1375 $force_active = true;
1376 }
1377 }
1378 }
1379 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1380 {
1381 $url = "";
1382 if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1383 // edit question properties
1384 $ilTabs->addTarget("edit_question",
1385 $url,
1386 array("editQuestion", "originalSyncForm", "save", "createGaps", "saveEdit"),
1387 $classname, "", $force_active);
1388 }
1389
1390 // add tab for question feedback within common class assQuestionGUI
1391 $this->addTab_QuestionFeedback($ilTabs);
1392
1393 // add tab for question hint within common class assQuestionGUI
1394 $this->addTab_QuestionHints($ilTabs);
1395
1396 // add tab for question's suggested solution within common class assQuestionGUI
1397 $this->addTab_SuggestedSolution($ilTabs, $classname);
1398
1399 // Assessment of questions sub menu entry
1400 if ($_GET["q_id"])
1401 {
1402 $ilTabs->addTarget("statistics",
1403 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1404 array("assessment"),
1405 $classname, "");
1406 }
1407
1408 $this->addBackTab($ilTabs);
1409 }
1410
1411 function getSpecificFeedbackOutput($active_id, $pass)
1412 {
1413 if( !$this->object->feedbackOBJ->specificAnswerFeedbackExists(array_values($this->object->gaps)) )
1414 {
1415 return '';
1416 }
1417
1418 global $lng;
1419
1420 $feedback = '<table class="test_specific_feedback"><tbody>';
1421
1422 foreach ($this->object->gaps as $index => $answer)
1423 {
1424 $caption = $lng->txt('gap').' '.($index+1) .': ';
1425
1426 $feedback .= '<tr><td>';
1427
1428 $feedback .= $caption .'</td><td>';
1429 $feedback .= $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
1430 $this->object->getId(), $index
1431 ) . '</td> </tr>';
1432 }
1433 $feedback .= '</tbody></table>';
1434
1435 return $this->object->prepareTextareaOutput($feedback, TRUE);
1436 }
1437
1448 {
1449 return array();
1450 }
1451
1462 {
1463 return array();
1464 }
1465
1474 public function getAggregatedAnswersView($relevant_answers)
1475 {
1476 $overview = array();
1477 $aggregation = array();
1478 foreach ($relevant_answers as $answer)
1479 {
1480 $overview[$answer['active_fi']][$answer['pass']][$answer['value1']] = $answer['value2'];
1481 }
1482
1483 foreach($overview as $active)
1484 {
1485 foreach ($active as $answer)
1486 {
1487 foreach ($answer as $option => $value)
1488 {
1489 $aggregation[$option][$value] = $aggregation[$option][$value] + 1;
1490 }
1491 }
1492 }
1493
1494 $html = '<div>';
1495 $i = 0;
1496 foreach ($this->object->getGaps() as $gap)
1497 {
1498 if ($gap->type == CLOZE_SELECT)
1499 {
1500 $html .= '<p>Gap '.$i . ' - SELECT</p>';
1501 $html .= '<ul>';
1502 $j = 0;
1503 foreach($gap->getItems() as $gap_item)
1504 {
1505 $aggregate = $aggregation[$i];
1506 $html .= '<li>' . $gap_item->getAnswerText() . ' - ' . ($aggregate[$j] ? $aggregate[$j] : 0) . '</li>';
1507 $j++;
1508 }
1509 $html .= '</ul>';
1510 }
1511
1512 if($gap->type == CLOZE_TEXT)
1513 {
1514 $present_elements = array();
1515 foreach($gap->getItems() as $item)
1516 {
1518 $present_elements[] = $item->getAnswertext();
1519 }
1520
1521 $html .= '<p>Gap ' . $i+1 . ' - TEXT</p>';
1522 $html .= '<ul>';
1523 $aggregate = (array)$aggregation[$i];
1524 foreach($aggregate as $answer => $count)
1525 {
1526 $show_mover = '';
1527 if(in_array($answer, $present_elements))
1528 {
1529 $show_mover = ' style="display: none;" ';
1530 }
1531
1532 $html .= '<li>' . $answer . ' - ' . $count
1533 . '&nbsp;<button class="clone_fields_add btn btn-link" ' . $show_mover . ' data-answer="'.$answer.'" name="add_gap_'.$i.'_0">
1534 <span class="sr-only"></span><span class="glyphicon glyphicon-plus"></span></button>
1535 </li>';
1536 }
1537 $html .= '</ul>';
1538 }
1539
1540 if($gap->type == CLOZE_NUMERIC)
1541 {
1542 $html .= '<p>Gap '.$i . ' - NUMERIC</p>';
1543 $html .= '<ul>';
1544 $j = 0;
1545 foreach($gap->getItems() as $gap_item)
1546 {
1547 $aggregate = (array)$aggregation[$i];
1548 foreach($aggregate as $answer => $count)
1549 {
1550 $html .= '<li>' . $answer . ' - ' . $count . '</li>';
1551 }
1552 $j++;
1553 }
1554 $html .= '</ul>';
1555 }
1556 $i++;
1557 $html .= '<hr />';
1558 }
1559
1560 $html .= '</div>';
1561 return $html;
1562 }
1563
1564 public function applyIndizesToGapText( $question_text )
1565 {
1566 $parts = explode( '[gap', $question_text );
1567 $i = 0;
1568 $question_text = '';
1569 foreach ( $parts as $part )
1570 {
1571 if ( $i == 0 )
1572 {
1573 $question_text .= $part;
1574 }
1575 else
1576 {
1577 $question_text .= '[gap ' . $i . $part;
1578 }
1579 $i++;
1580 }
1581 return $question_text;
1582 }
1583
1584 public function removeIndizesFromGapText( $question_text )
1585 {
1586 $parts = preg_split( '/\[gap \d*\]/', $question_text );
1587 $question_text = implode( '[gap]', $parts );
1588 return $question_text;
1589 }
1590}
$test
Definition: Utf8Test.php:85
$_GET["client_id"]
Class for cloze question numeric answers.
Cloze test question GUI representation.
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
__construct($id=-1)
assClozeTestGUI constructor
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
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.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
Creates a preview output of the question.
$gapIndex
A temporary variable to store gap indexes of ilCtrl commands in the getCommand method.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
Adds the question specific forms parts to a question property form gui.
getSpecificFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
populateGapSizeFormPart($form, $gap, $gapCounter)
setQuestionTabs()
Sets the ILIAS tabs for this question type.
populateTextGapFormPart($form, $gap, $gapCounter)
Populates the form-part for a text gap.
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...
removeIndizesFromGapText( $question_text)
getTestOutput( $active_id, $pass=NULL, $is_postponed=FALSE, $use_post_solutions=FALSE, $show_feedback=FALSE)
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.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
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.
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
removegap()
Remove a gap answer.
applyIndizesToGapText( $question_text)
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
writePostData()
Evaluates a posted edit form and writes the form data in the question object.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
addBackTab(ilTabsGUI $ilTabs)
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.
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.
& _getUsedHTMLTags($a_module="")
Returns an array of all allowed HTML tags for text editing.
_getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static getManualFeedback($active_id, $question_id, $pass)
Retrieves the manual feedback for a question in a test.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
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
$_POST['username']
Definition: cron.php:12
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...
$cmd
Definition: sahs_server.php:35
if(!is_array($argv)) $options
$errors