ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
4 require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5 require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7 
23 {
27  private $gapIndex;
28 
34  public function __construct($id = -1)
35  {
37  include_once "./Modules/TestQuestionPool/classes/class.assClozeTest.php";
38  $this->object = new assClozeTest();
39  if ($id >= 0)
40  {
41  $this->object->loadFromDb($id);
42  }
43  }
44 
45  function getCommand($cmd)
46  {
47  if (preg_match("/^(removegap|addgap)_(\d+)$/", $cmd, $matches))
48  {
49  $cmd = $matches[1];
50  $this->gapIndex = $matches[2];
51  }
52  return $cmd;
53  }
54 
63  function writePostData($always = false)
64  {
65  // Bugfix for mantis: 14034
66  $save_return = true;
67  if (is_array( $_POST['gap'] ))
68  {
69  foreach ($_POST['gap'] as $idx => $hidden)
70  {
71  $clozetype = $_POST['clozetype_' . $idx];
72 
73  $db_gap = $this->object->getGap($idx);
74  if( !is_object($db_gap) || $db_gap->getType() != $clozetype )
75  {
76  // if gap-type has been changed: set always = true and ignore "required inputs" and save new gap-type
77  $always = true;
78  // do not accept "save & return" action
79  $save_return = false;
80  }
81  }
82  }
83 
84  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
85  if (!$hasErrors)
86  {
87  $question_text = $_POST['question'];
88  $question_text = $this->removeIndizesFromGapText( $question_text );
89  $_POST['question'] = $question_text;
90  $this->object->setQuestion($question_text);
91 
93  $this->object->setClozeText($_POST["question"]);
95  //$this->object->flushGaps();
97  $this->saveTaxonomyAssignments();
98  if($save_return == false && $always == true)
99  {
100  $question_text = $_POST['question'];
101  $question_text = $this->applyIndizesToGapText($question_text);
102  $_POST['question'] = $question_text;
103 
104  return $this->editQuestion(true);
105  }
106  return 0;
107  }
108 
109  $question_text = $_POST['question'];
110  $question_text = $this->applyIndizesToGapText($question_text);
111  $_POST['question'] = $question_text;
112  return 1;
113  }
114 
115  public function writeAnswerSpecificPostData($always = false)
116  {
117  if (is_array( $_POST['gap'] ))
118  {
119  if ( $this->ctrl->getCmd() != 'createGaps' )
120  {
121  $this->object->clearGapAnswers();
122  }
123 
124  foreach ($_POST['gap'] as $idx => $hidden)
125  {
126  $clozetype = $_POST['clozetype_' . $idx];
127 
128  $this->object->setGapType( $idx, $clozetype );
129 
130  switch($clozetype)
131  {
132  case CLOZE_TEXT:
133 
134  $this->object->setGapShuffle( $idx, 0 );
135 
136  if ($this->ctrl->getCmd() != 'createGaps')
137  {
138  if (is_array( $_POST['gap_' . $idx]['answer'] ))
139  {
140  foreach ($_POST['gap_' . $idx]['answer'] as $order => $value)
141  {
142  $this->object->addGapAnswer( $idx, $order, $value );
143  }
144  }
145  else
146  {
147  $this->object->addGapAnswer( $idx, 0, '' );
148  }
149  }
150 
151  if (is_array( $_POST['gap_' . $idx]['points'] ))
152  {
153  foreach ($_POST['gap_' . $idx]['points'] as $order => $value)
154  {
155  $this->object->setGapAnswerPoints( $idx, $order, $value );
156  }
157  }
158 
159  break;
160 
161  case CLOZE_SELECT:
162 
163  $this->object->setGapShuffle( $idx, (int)(isset($_POST["shuffle_$idx"]) && $_POST["shuffle_$idx"]) );
164 
165  if ($this->ctrl->getCmd() != 'createGaps')
166  {
167  if (is_array( $_POST['gap_' . $idx]['answer'] ))
168  {
169  foreach ($_POST['gap_' . $idx]['answer'] as $order => $value)
170  {
171  $this->object->addGapAnswer( $idx, $order, $value );
172  }
173  }
174  else
175  {
176  $this->object->addGapAnswer( $idx, 0, '' );
177  }
178  }
179 
180  if (is_array( $_POST['gap_' . $idx]['points'] ))
181  {
182  foreach ($_POST['gap_' . $idx]['points'] as $order => $value)
183  {
184  $this->object->setGapAnswerPoints( $idx, $order, $value );
185  }
186  }
187 
188  break;
189 
190  case CLOZE_NUMERIC:
191 
192  $this->object->setGapShuffle( $idx, 0 );
193 
194  $gap = $this->object->getGap($idx);
195  if (!$gap) break;
196 
197  $this->object->getGap($idx)->clearItems();
198 
199  if (array_key_exists( 'gap_' . $idx . '_numeric', $_POST ))
200  {
201  #if ($this->ctrl->getCmd() != 'createGaps')
202  #{
203  $this->object->addGapAnswer(
204  $idx, 0, str_replace(",", ".", $_POST['gap_' . $idx . '_numeric'])
205  );
206  #}
207 
208  $this->object->setGapAnswerLowerBound(
209  $idx, 0, str_replace(",", ".", $_POST['gap_' . $idx . '_numeric_lower'])
210  );
211 
212  $this->object->setGapAnswerUpperBound(
213  $idx, 0, str_replace( ",", ".", $_POST['gap_' . $idx . '_numeric_upper'])
214  );
215 
216  $this->object->setGapAnswerPoints( $idx, 0, $_POST['gap_' . $idx . '_numeric_points'] );
217  }
218  else
219  {
220  #if ($this->ctrl->getCmd() != 'createGaps')
221  #{
222  $this->object->addGapAnswer($idx, 0, '');
223  #}
224 
225  $this->object->setGapAnswerLowerBound($idx, 0, '');
226 
227  $this->object->setGapAnswerUpperBound($idx, 0, '');
228  }
229 
230  break;
231  }
232  }
233  if ($this->ctrl->getCmd() != 'createGaps')
234  {
235  $this->object->updateClozeTextFromGaps();
236  }
237  }
238  }
239 
240  public function writeQuestionSpecificPostData($always = false)
241  {
242  $this->object->setTextgapRating( $_POST["textgap_rating"] );
243  $this->object->setIdenticalScoring( $_POST["identical_scoring"] );
244  $this->object->setFixedTextLength( $_POST["fixedTextLength"] );
245  }
246 
252  public function editQuestion($checkonly = FALSE)
253  {
254  $save = $this->isSaveCommand();
255  $this->getQuestionTemplate();
256 
257  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
258  $form = new ilPropertyFormGUI();
259  $form->setFormAction($this->ctrl->getFormAction($this));
260  $form->setTitle($this->outQuestionType());
261  $form->setMultipart(FALSE);
262  $form->setTableWidth("100%");
263  $form->setId("assclozetest");
264 
265  // title, author, description, question, working time (assessment mode)
266  $this->addBasicQuestionFormProperties($form);
267 
268  // Modify "instructive" question textbox... get rid of this crap asap.
269  $q_item = $form->getItemByPostVar("question");
270  $q_item->setValue($this->applyIndizesToGapText($q_item->getValue()));
271  $q_item->setInfo($this->lng->txt("close_text_hint"));
272  $q_item->setTitle($this->lng->txt("cloze_text"));
273 
274  $this->populateQuestionSpecificFormPart( $form );
275  $this->populateAnswerSpecificFormPart( $form );
276  $this->populateTaxonomyFormSection($form);
277 
278  $this->addQuestionFormCommandButtons($form);
279 
280  $errors = false;
281 
282  if ($save)
283  {
284  $form->setValuesByPost();
285  $errors = !$form->checkInput();
286  $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we
287  // need this if we don't want to have duplication of backslashes
288  if ($errors) $checkonly = false;
289  }
290 
291  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
292  return $errors;
293  }
294 
296  {
297  // title
298  $title = new ilTextInputGUI($this->lng->txt("title"), "title");
299  $title->setValue($this->object->getTitle());
300  $title->setRequired(TRUE);
301  $form->addItem($title);
302 
303  if (!$this->object->getSelfAssessmentEditingMode())
304  {
305  // author
306  $author = new ilTextInputGUI($this->lng->txt("author"), "author");
307  $author->setValue($this->object->getAuthor());
308  $author->setRequired(TRUE);
309  $form->addItem($author);
310 
311  // description
312  $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
313  $description->setValue($this->object->getComment());
314  $description->setRequired(FALSE);
315  $form->addItem($description);
316  }
317  else
318  {
319  // author as hidden field
320  $hi = new ilHiddenInputGUI("author");
321  $author = ilUtil::prepareFormOutput($this->object->getAuthor());
322  if (trim($author) == "")
323  {
324  $author = "-";
325  }
326  $hi->setValue($author);
327  $form->addItem($hi);
328 
329  }
330 
331  // questiontext
332  $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
333  $question->setValue($this->object->prepareTextareaOutput($this->object->getQuestion()));
334  $question->setRequired(TRUE);
335  $question->setRows(10);
336  $question->setCols(80);
337  if (!$this->object->getSelfAssessmentEditingMode())
338  {
339  if( $this->object->getAdditionalContentEditingMode() == assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_DEFAULT )
340  {
341  $question->setUseRte(TRUE);
342  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
343  $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
344  $question->addPlugin("latex");
345  $question->addButton("latex");
346  $question->addButton("pastelatex");
347  $question->setRTESupport($this->object->getId(), "qpl", "assessment");
348  }
349  }
350  else
351  {
352  $question->setRteTags(self::getSelfAssessmentTags());
353  $question->setUseTagsForRteOnly(false);
354  }
355  $form->addItem($question);
356 
357  $tpl = new ilTemplate("tpl.il_as_qpl_cloze_gap_button_code.html", TRUE, TRUE, "Modules/TestQuestionPool");
358  $tpl->setVariable('INSERT_GAP', $this->lng->txt('insert_gap'));
359  $tpl->setVariable('CREATE_GAPS', $this->lng->txt('create_gaps'));
360  $tpl->parseCurrentBlock();
361  $button = new ilCustomInputGUI('&nbsp;','');
362  $button->setHtml($tpl->get());
363  $form->addItem($button);
364 
365  if (!$this->object->getSelfAssessmentEditingMode())
366  {
367  // duration
368  $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
369  $duration->setShowHours(TRUE);
370  $duration->setShowMinutes(TRUE);
371  $duration->setShowSeconds(TRUE);
372  $ewt = $this->object->getEstimatedWorkingTime();
373  $duration->setHours($ewt["h"]);
374  $duration->setMinutes($ewt["m"]);
375  $duration->setSeconds($ewt["s"]);
376  $duration->setRequired(FALSE);
377  $form->addItem($duration);
378  }
379  else
380  {
381  // number of tries
382  if (strlen($this->object->getNrOfTries()))
383  {
384  $nr_tries = $this->object->getNrOfTries();
385  }
386  else
387  {
388  $nr_tries = $this->object->getDefaultNrOfTries();
389  }
390  /*if ($nr_tries <= 0)
391  {
392  $nr_tries = 1;
393  }*/
394 
395  if ($nr_tries < 0)
396  {
397  $nr_tries = 0;
398  }
399 
400  $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
401  $ni->setValue($nr_tries);
402  //$ni->setMinValue(1);
403  $ni->setMinValue(0);
404  $ni->setSize(5);
405  $ni->setMaxLength(5);
406  $ni->setRequired(true);
407  $form->addItem($ni);
408  }
409  }
410 
412  {
413  // text rating
414  if (!$this->object->getSelfAssessmentEditingMode())
415  {
416  $textrating = new ilSelectInputGUI($this->lng->txt( "text_rating" ), "textgap_rating");
417  $text_options = array(
418  "ci" => $this->lng->txt( "cloze_textgap_case_insensitive" ),
419  "cs" => $this->lng->txt( "cloze_textgap_case_sensitive" ),
420  "l1" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "1" ),
421  "l2" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "2" ),
422  "l3" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "3" ),
423  "l4" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "4" ),
424  "l5" => sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "5" )
425  );
426  $textrating->setOptions( $text_options );
427  $textrating->setValue( $this->object->getTextgapRating() );
428  $form->addItem( $textrating );
429 
430  // text field length
431  $fixedTextLength = new ilNumberInputGUI($this->lng->txt( "cloze_fixed_textlength" ), "fixedTextLength");
432  $ftl = $this->object->getFixedTextLength();
433  if ($ftl == null)
434  {
435  $ftl = 0;
436  }
437  $fixedTextLength->setValue( ilUtil::prepareFormOutput( $ftl ) );
438  $fixedTextLength->setMinValue( 0 );
439  $fixedTextLength->setSize( 3 );
440  $fixedTextLength->setMaxLength( 6 );
441  $fixedTextLength->setInfo( $this->lng->txt( 'cloze_fixed_textlength_description' ) );
442  $fixedTextLength->setRequired( false );
443  $form->addItem( $fixedTextLength );
444 
445  // identical scoring
446  $identical_scoring = new ilCheckboxInputGUI($this->lng->txt( "identical_scoring" ), "identical_scoring");
447  $identical_scoring->setValue( 1 );
448  $identical_scoring->setChecked( $this->object->getIdenticalScoring() );
449  $identical_scoring->setInfo( $this->lng->txt( 'identical_scoring_desc' ) );
450  $identical_scoring->setRequired( FALSE );
451  $form->addItem( $identical_scoring );
452  }
453  return $form;
454  }
455 
457  {
458  for ($gapCounter = 0; $gapCounter < $this->object->getGapCount(); $gapCounter++)
459  {
460  $this->populateGapFormPart( $form, $gapCounter );
461  }
462  return $form;
463  }
464 
476  protected function populateGapFormPart($form, $gapCounter)
477  {
478  $gap = $this->object->getGap( $gapCounter );
479 
480  if ($gap == null)
481  {
482  return $form;
483  }
484 
485  $header = new ilFormSectionHeaderGUI();
486  $header->setTitle( $this->lng->txt( "gap" ) . " " . ($gapCounter + 1) );
487  $form->addItem( $header );
488 
489  $gapcounter = new ilHiddenInputGUI("gap[$gapCounter]");
490  $gapcounter->setValue( $gapCounter );
491  $form->addItem( $gapcounter );
492 
493  $gaptype = new ilSelectInputGUI($this->lng->txt( 'type' ), "clozetype_$gapCounter");
494  $options = array(
495  0 => $this->lng->txt( "text_gap" ),
496  1 => $this->lng->txt( "select_gap" ),
497  2 => $this->lng->txt( "numeric_gap" )
498  );
499  $gaptype->setOptions( $options );
500  $gaptype->setValue( $gap->getType() );
501  $form->addItem( $gaptype );
502 
503  if ($gap->getType() == CLOZE_TEXT)
504  {
505  if (count( $gap->getItemsRaw() ) == 0)
506  {
507  $gap->addItem( new assAnswerCloze("", 0, 0) );
508  }
509 
510  $this->populateTextGapFormPart( $form, $gap, $gapCounter );
511  }
512  else if ($gap->getType() == CLOZE_SELECT)
513  {
514  if (count( $gap->getItemsRaw() ) == 0)
515  {
516  $gap->addItem( new assAnswerCloze("", 0, 0) );
517  }
518  $this->populateSelectGapFormPart( $form, $gap, $gapCounter );
519  }
520  else if ($gap->getType() == CLOZE_NUMERIC)
521  {
522  if (count( $gap->getItemsRaw() ) == 0)
523  {
524  $gap->addItem( new assAnswerCloze("", 0, 0) );
525  }
526 
527  foreach ($gap->getItemsRaw() as $item)
528  {
529  $this->populateNumericGapFormPart( $form, $item, $gapCounter );
530  }
531  }
532  return $form;
533  }
534 
547  protected function populateSelectGapFormPart($form, $gap, $gapCounter)
548  {
549  include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
550  include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
551  $values = new ilAnswerWizardInputGUI($this->lng->txt( "values" ), "gap_" . $gapCounter . "");
552  $values->setRequired( true );
553  $values->setQuestionObject( $this->object );
554  $values->setSingleline( true );
555  $values->setAllowMove( false );
556 
557  $values->setValues( $gap->getItemsRaw() );
558  $form->addItem( $values );
559 
560  // shuffle
561  $shuffle = new ilCheckboxInputGUI($this->lng->txt( "shuffle_answers" ), "shuffle_" . $gapCounter . "");
562  $shuffle->setValue( 1 );
563  $shuffle->setChecked( $gap->getShuffle() );
564  $shuffle->setRequired( FALSE );
565  $form->addItem( $shuffle );
566  return $form;
567  }
568 
580  protected function populateTextGapFormPart($form, $gap, $gapCounter)
581  {
582  // Choices
583  include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
584  include_once "./Modules/TestQuestionPool/classes/class.assAnswerCloze.php";
585  $values = new ilAnswerWizardInputGUI($this->lng->txt( "values" ), "gap_" . $gapCounter . "");
586  $values->setRequired( true );
587  $values->setQuestionObject( $this->object );
588  $values->setSingleline( true );
589  $values->setAllowMove( false );
590  $values->setValues( $gap->getItemsRaw() );
591  $form->addItem( $values );
592 
593  if( $this->object->getFixedTextLength() > 0 )
594  {
595  $values->setSize( $this->object->getFixedTextLength() );
596  $values->setMaxLength( $this->object->getFixedTextLength() );
597  }
598 
599  return $form;
600  }
601 
613  protected function populateNumericGapFormPart($form, $gap, $gapCounter)
614  {
615  // #8944: the js-based ouput in self-assessment cannot support formulas
616  if (!$this->object->getSelfAssessmentEditingMode())
617  {
618  $value = new ilFormulaInputGUI($this->lng->txt( 'value' ), "gap_" . $gapCounter . "_numeric");
619  $value->setInlineStyle( 'text-align: right;' );
620 
621  $lowerbound = new ilFormulaInputGUI($this->lng->txt( 'range_lower_limit'), "gap_" . $gapCounter . "_numeric_lower");
622  $lowerbound->setInlineStyle( 'text-align: right;' );
623 
624  $upperbound = new ilFormulaInputGUI($this->lng->txt( 'range_upper_limit'), "gap_" . $gapCounter . "_numeric_upper");
625  $upperbound->setInlineStyle( 'text-align: right;' );
626  }
627  else
628  {
629  $value = new ilNumberInputGUI($this->lng->txt( 'value' ), "gap_" . $gapCounter . "_numeric");
630  $value->allowDecimals( true );
631 
632  $lowerbound = new ilNumberInputGUI($this->lng->txt( 'range_lower_limit'), "gap_" . $gapCounter . "_numeric_lower");
633  $lowerbound->allowDecimals( true );
634 
635  $upperbound = new ilNumberInputGUI($this->lng->txt( 'range_upper_limit'), "gap_" . $gapCounter . "_numeric_upper");
636  $upperbound->allowDecimals( true );
637  }
638 
639  $value->setSize( 10 );
640  $value->setValue( ilUtil::prepareFormOutput( $gap->getAnswertext() ) );
641  $value->setRequired( true );
642  $form->addItem( $value );
643 
644  $lowerbound->setSize( 10 );
645  $lowerbound->setRequired( true );
646  $lowerbound->setValue( ilUtil::prepareFormOutput( $gap->getLowerBound() ) );
647  $form->addItem( $lowerbound );
648 
649  $upperbound->setSize( 10 );
650  $upperbound->setRequired( true );
651  $upperbound->setValue( ilUtil::prepareFormOutput( $gap->getUpperBound() ) );
652  $form->addItem( $upperbound );
653 
654  if( $this->object->getFixedTextLength() > 0 )
655  {
656  $value->setSize( $this->object->getFixedTextLength() );
657  $value->setMaxLength( $this->object->getFixedTextLength() );
658  $lowerbound->setSize( $this->object->getFixedTextLength() );
659  $lowerbound->setMaxLength( $this->object->getFixedTextLength() );
660  $upperbound->setSize( $this->object->getFixedTextLength() );
661  $upperbound->setMaxLength( $this->object->getFixedTextLength() );
662  }
663 
664  $points = new ilNumberInputGUI($this->lng->txt( 'points' ), "gap_" . $gapCounter . "_numeric_points");
665  $points->allowDecimals(true);
666  $points->setSize( 3 );
667  $points->setRequired( true );
668  $points->setValue( ilUtil::prepareFormOutput( $gap->getPoints() ) );
669  $form->addItem( $points );
670  return $form;
671  }
672 
676  public function createGaps()
677  {
678  $this->writePostData(true);
679  $this->object->saveToDb();
680  $this->editQuestion();
681  }
682 
686  function removegap()
687  {
688  $this->writePostData(true);
689  $this->object->deleteAnswerText($this->gapIndex, key($_POST['cmd']['removegap_' . $this->gapIndex]));
690  $this->editQuestion();
691  }
692 
696  function addgap()
697  {
698  $this->writePostData(true);
699  $this->object->addGapAnswer($this->gapIndex, key($_POST['cmd']['addgap_' . $this->gapIndex])+1, "");
700  $this->editQuestion();
701  }
702 
715  $formaction,
716  $active_id,
717  $pass = NULL,
718  $is_postponed = FALSE,
719  $use_post_solutions = FALSE
720  )
721  {
722  $test_output = $this->getTestOutput($active_id, $pass, $is_postponed, $use_post_solutions);
723  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
724  $this->tpl->setVariable("FORMACTION", $formaction);
725  }
726 
735  function getPreview($show_question_only = FALSE)
736  {
737 
738 
739  // generate the question output
740  include_once "./Services/UICore/classes/class.ilTemplate.php";
741  $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
742  $output = $this->object->getClozeText();
743  foreach ($this->object->getGaps() as $gap_index => $gap)
744  {
745  switch ($gap->getType())
746  {
747  case CLOZE_TEXT:
748  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_text.html", TRUE, TRUE, "Modules/TestQuestionPool");
749  $gaptemplate->setVariable("TEXT_GAP_SIZE", $this->object->getFixedTextLength() ? $this->object->getFixedTextLength() : $gap->getMaxWidth());
750  $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
751  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
752  break;
753  case CLOZE_SELECT:
754  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_select.html", TRUE, TRUE, "Modules/TestQuestionPool");
755  foreach ($gap->getItems() as $item)
756  {
757  $gaptemplate->setCurrentBlock("select_gap_option");
758  $gaptemplate->setVariable("SELECT_GAP_VALUE", $item->getOrder());
759  $gaptemplate->setVariable("SELECT_GAP_TEXT", ilUtil::prepareFormOutput($item->getAnswerText()));
760  $gaptemplate->parseCurrentBlock();
761  }
762  $gaptemplate->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
763  $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
764  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
765  break;
766  case CLOZE_NUMERIC:
767  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_numeric.html", TRUE, TRUE, "Modules/TestQuestionPool");
768  $gaptemplate->setVariable("TEXT_GAP_SIZE", $this->object->getFixedTextLength() ? $this->object->getFixedTextLength() : $gap->getMaxWidth());
769  $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
770  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
771  break;
772  }
773  }
774  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($output, TRUE));
775  $questionoutput = $template->get();
776  if (!$show_question_only)
777  {
778  // get page object output
779  $questionoutput = $this->getILIASPage($questionoutput);
780  }
781  return $questionoutput;
782  }
783 
800  $active_id,
801  $pass = NULL,
802  $graphicalOutput = FALSE,
803  $result_output = FALSE,
804  $show_question_only = TRUE,
805  $show_feedback = FALSE,
806  $show_correct_solution = FALSE,
807  $show_manual_scoring = FALSE,
808  $show_question_text = TRUE
809  )
810  {
811  // get the solution of the user for the active pass or from the last pass if allowed
812  $user_solution = array();
813  if (($active_id > 0) && (!$show_correct_solution))
814  {
815  // get the solutions of a user
816  $user_solution =& $this->object->getSolutionValues($active_id, $pass);
817  if (!is_array($user_solution))
818  {
819  $user_solution = array();
820  }
821  } else {
822  foreach ($this->object->gaps as $index => $gap)
823  {
824  $user_solution = array();
825 
826  }
827  }
828 
829  include_once "./Services/UICore/classes/class.ilTemplate.php";
830  $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
831  $output = $this->object->getClozeText();
832  foreach ($this->object->getGaps() as $gap_index => $gap)
833  {
834  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_output_solution_gap.html", TRUE, TRUE, "Modules/TestQuestionPool");
835  $found = array();
836  foreach ($user_solution as $solutionarray)
837  {
838  if ($solutionarray["value1"] == $gap_index) $found = $solutionarray;
839  }
840 
841  if ($active_id)
842  {
843  if ($graphicalOutput)
844  {
845  // output of ok/not ok icons for user entered solutions
846  $details = $this->object->calculateReachedPoints($active_id, $pass, TRUE);
847  $check = $details[$gap_index];
848  if ($check["best"])
849  {
850  $gaptemplate->setCurrentBlock("icon_ok");
851  $gaptemplate->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.png"));
852  $gaptemplate->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
853  $gaptemplate->parseCurrentBlock();
854  }
855  else
856  {
857  $gaptemplate->setCurrentBlock("icon_not_ok");
858  if ($check["positive"])
859  {
860  $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.png"));
861  $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
862  }
863  else
864  {
865  $gaptemplate->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.png"));
866  $gaptemplate->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
867  }
868  $gaptemplate->parseCurrentBlock();
869  }
870  }
871  }
872  if ($result_output)
873  {
874  $points = $this->object->getMaximumGapPoints($gap_index);
875  $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
876  $gaptemplate->setCurrentBlock("result_output");
877  $gaptemplate->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
878  $gaptemplate->parseCurrentBlock();
879  }
880  switch ($gap->getType())
881  {
882  case CLOZE_TEXT:
883  $solutiontext = "";
884  if (($active_id > 0) && (!$show_correct_solution))
885  {
886  if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0))
887  {
888  for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
889  {
890  $solutiontext .= "&nbsp;";
891  }
892  }
893  else
894  {
895  $solutiontext = ilUtil::prepareFormOutput($found["value2"]);
896  }
897  }
898  else
899  {
900  $solutiontext = ilUtil::prepareFormOutput($gap->getBestSolutionOutput());
901  }
902  $gaptemplate->setVariable("SOLUTION", $solutiontext);
903  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
904  break;
905  case CLOZE_SELECT:
906  $solutiontext = "";
907  if (($active_id > 0) && (!$show_correct_solution))
908  {
909  if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0))
910  {
911  for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
912  {
913  $solutiontext .= "&nbsp;";
914  }
915  }
916  else
917  {
918  $item = $gap->getItem($found["value2"]);
919  if (is_object($item))
920  {
921  $solutiontext = ilUtil::prepareFormOutput($item->getAnswertext());
922  }
923  else
924  {
925  for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
926  {
927  $solutiontext .= "&nbsp;";
928  }
929  }
930  }
931  }
932  else
933  {
934  $solutiontext = ilUtil::prepareFormOutput($gap->getBestSolutionOutput());
935  }
936  $gaptemplate->setVariable("SOLUTION", $solutiontext);
937  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
938  break;
939  case CLOZE_NUMERIC:
940  $solutiontext = "";
941  if (($active_id > 0) && (!$show_correct_solution))
942  {
943  if ((count($found) == 0) || (strlen(trim($found["value2"])) == 0))
944  {
945  for ($chars = 0; $chars < $gap->getMaxWidth(); $chars++)
946  {
947  $solutiontext .= "&nbsp;";
948  }
949  }
950  else
951  {
952  $solutiontext = ilUtil::prepareFormOutput($found["value2"]);
953  }
954  }
955  else
956  {
957  $solutiontext = ilUtil::prepareFormOutput($gap->getBestSolutionOutput());
958  }
959  $gaptemplate->setVariable("SOLUTION", $solutiontext);
960  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
961  break;
962  }
963  }
964 
965  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($output, TRUE));
966  // generate the question output
967  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
968  $questionoutput = $template->get();
969 
970  $feedback = '';
971  if($show_feedback)
972  {
973  $fb = $this->getGenericFeedbackOutput($active_id, $pass);
974  $feedback .= strlen($fb) ? $fb : '';
975 
976  $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
977  $feedback .= strlen($fb) ? $fb : '';
978  }
979  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $feedback);
980 
981  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
982 
983  $solutionoutput = $solutiontemplate->get();
984 
985  if (!$show_question_only)
986  {
987  // get page object output
988  $solutionoutput = '<div class="ilc_question_Standard">'.$solutionoutput."</div>";
989  }
990 
991  return $solutionoutput;
992  }
993 
994  public function getAnswerFeedbackOutput($active_id, $pass)
995  {
996  include_once "./Modules/Test/classes/class.ilObjTest.php";
997  $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
998  if (strlen($manual_feedback))
999  {
1000  return $manual_feedback;
1001  }
1002  $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1003  $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1004  if (strlen($correct_feedback.$incorrect_feedback))
1005  {
1006  $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1007  $max_points = $this->object->getMaximumPoints();
1008  if ($reached_points == $max_points)
1009  {
1010  $output .= $correct_feedback;
1011  }
1012  else
1013  {
1014  $output .= $incorrect_feedback;
1015  }
1016  }
1017  $test = new ilObjTest($this->object->active_id);
1018  return $this->object->prepareTextareaOutput($output, TRUE);
1019  }
1020 
1021  function getTestOutput(
1022  $active_id,
1023  $pass = NULL,
1024  $is_postponed = FALSE,
1025  $use_post_solutions = FALSE,
1026  $show_feedback = FALSE
1027  )
1028  {
1029  // get the solution of the user for the active pass or from the last pass if allowed
1030  $user_solution = array();
1031  if ($active_id)
1032  {
1033  include_once "./Modules/Test/classes/class.ilObjTest.php";
1034  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
1035  {
1036  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
1037  }
1038  $user_solution =& $this->object->getSolutionValues($active_id, $pass);
1039  if (!is_array($user_solution))
1040  {
1041  $user_solution = array();
1042  }
1043  }
1044 
1045  // generate the question output
1046  include_once "./Services/UICore/classes/class.ilTemplate.php";
1047  $template = new ilTemplate("tpl.il_as_qpl_cloze_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
1048  $output = $this->object->getClozeText();
1049  foreach ($this->object->getGaps() as $gap_index => $gap)
1050  {
1051  switch ($gap->getType())
1052  {
1053  case CLOZE_TEXT:
1054  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_text.html", TRUE, TRUE, "Modules/TestQuestionPool");
1055  $gaptemplate->setVariable("TEXT_GAP_SIZE", $this->object->getFixedTextLength() ? $this->object->getFixedTextLength() : $gap->getMaxWidth());
1056  $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1057  foreach ($user_solution as $solution)
1058  {
1059  if (strcmp($solution["value1"], $gap_index) == 0)
1060  {
1061  $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($solution["value2"]) . "\"");
1062  }
1063  }
1064  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1065  break;
1066  case CLOZE_SELECT:
1067  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_select.html", TRUE, TRUE, "Modules/TestQuestionPool");
1068  foreach ($gap->getItems() as $item)
1069  {
1070  $gaptemplate->setCurrentBlock("select_gap_option");
1071  $gaptemplate->setVariable("SELECT_GAP_VALUE", $item->getOrder());
1072  $gaptemplate->setVariable("SELECT_GAP_TEXT", ilUtil::prepareFormOutput($item->getAnswerText()));
1073  foreach ($user_solution as $solution)
1074  {
1075  if (strcmp($solution["value1"], $gap_index) == 0)
1076  {
1077  if (strcmp($solution["value2"], $item->getOrder()) == 0)
1078  {
1079  $gaptemplate->setVariable("SELECT_GAP_SELECTED", " selected=\"selected\"");
1080  }
1081  }
1082  }
1083  $gaptemplate->parseCurrentBlock();
1084  }
1085  $gaptemplate->setVariable("PLEASE_SELECT", $this->lng->txt("please_select"));
1086  $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1087  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1088  break;
1089  case CLOZE_NUMERIC:
1090  $gaptemplate = new ilTemplate("tpl.il_as_qpl_cloze_question_gap_numeric.html", TRUE, TRUE, "Modules/TestQuestionPool");
1091  $gaptemplate->setVariable("TEXT_GAP_SIZE", $this->object->getFixedTextLength() ? $this->object->getFixedTextLength() : $gap->getMaxWidth());
1092  $gaptemplate->setVariable("GAP_COUNTER", $gap_index);
1093  foreach ($user_solution as $solution)
1094  {
1095  if (strcmp($solution["value1"], $gap_index) == 0)
1096  {
1097  $gaptemplate->setVariable("VALUE_GAP", " value=\"" . ilUtil::prepareFormOutput($solution["value2"]) . "\"");
1098  }
1099  }
1100  $output = preg_replace("/\[gap\].*?\[\/gap\]/", $gaptemplate->get(), $output, 1);
1101  break;
1102  }
1103  }
1104 
1105  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($output, TRUE));
1106  $questionoutput = $template->get();
1107  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
1108  return $pageoutput;
1109  }
1110 
1118  public function setQuestionTabs()
1119  {
1120  global $rbacsystem, $ilTabs;
1121 
1122  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1123  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1124  $q_type = $this->object->getQuestionType();
1125 
1126  if (strlen($q_type))
1127  {
1128  $classname = $q_type . "GUI";
1129  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1130  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1131 # $this->ctrl->setParameterByClass(strtolower($classname), 'prev_qid', $_REQUEST['prev_qid']);
1132  }
1133 
1134  if ($_GET["q_id"])
1135  {
1136  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1137  {
1138  // edit page
1139  $ilTabs->addTarget("edit_page",
1140  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1141  array("edit", "insert", "exec_pg"),
1142  "", "", $force_active);
1143  }
1144 
1145  // edit page
1146  $ilTabs->addTarget("preview",
1147  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "preview"),
1148  array("preview"),
1149  "ilAssQuestionPageGUI", "", $force_active);
1150  }
1151 
1152  $force_active = false;
1153  $commands = $_POST["cmd"];
1154  if (is_array($commands))
1155  {
1156  foreach ($commands as $key => $value)
1157  {
1158  if (preg_match("/^removegap_.*/", $key, $matches) ||
1159  preg_match("/^addgap_.*/", $key, $matches)
1160  )
1161  {
1162  $force_active = true;
1163  }
1164  }
1165  }
1166  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1167  {
1168  $url = "";
1169  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1170  // edit question properties
1171  $ilTabs->addTarget("edit_question",
1172  $url,
1173  array("editQuestion", "originalSyncForm", "save", "createGaps", "saveEdit"),
1174  $classname, "", $force_active);
1175  }
1176 
1177  // add tab for question feedback within common class assQuestionGUI
1178  $this->addTab_QuestionFeedback($ilTabs);
1179 
1180  // add tab for question hint within common class assQuestionGUI
1181  $this->addTab_QuestionHints($ilTabs);
1182 
1183  if ($_GET["q_id"])
1184  {
1185  $ilTabs->addTarget("solution_hint",
1186  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
1187  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
1188  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
1189  ),
1190  $classname,
1191  ""
1192  );
1193  }
1194 
1195  // Assessment of questions sub menu entry
1196  if ($_GET["q_id"])
1197  {
1198  $ilTabs->addTarget("statistics",
1199  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1200  array("assessment"),
1201  $classname, "");
1202  }
1203 
1204  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
1205  {
1206  $ref_id = $_GET["calling_test"];
1207  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
1208 
1209  global $___test_express_mode;
1210 
1211  if (!$_GET['test_express_mode'] && !$___test_express_mode) {
1212  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
1213  }
1214  else {
1216  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
1217  }
1218  }
1219  else
1220  {
1221  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
1222  }
1223  }
1224 
1225  function getSpecificFeedbackOutput($active_id, $pass)
1226  {
1227  if( !$this->object->feedbackOBJ->specificAnswerFeedbackExists(array_values($this->object->gaps)) )
1228  {
1229  return '';
1230  }
1231 
1232  global $lng;
1233 
1234  $feedback = '<table><tbody>';
1235 
1236  foreach ($this->object->gaps as $index => $answer)
1237  {
1238  $caption = $lng->txt('gap').' '.($index+1) .': ';
1239 
1240  $feedback .= '<tr><td>';
1241 
1242  $feedback .= $caption .'</td><td>';
1243  $feedback .= $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
1244  $this->object->getId(), $index
1245  ) . '</td> </tr>';
1246  }
1247  $feedback .= '</tbody></table>';
1248 
1249  return $this->object->prepareTextareaOutput($feedback, TRUE);
1250  }
1251 
1252 
1253  public function applyIndizesToGapText( $question_text )
1254  {
1255  $parts = explode( '[gap', $question_text );
1256  $i = 0;
1257  $question_text = '';
1258  foreach ( $parts as $part )
1259  {
1260  if ( $i == 0 )
1261  {
1262  $question_text .= $part;
1263  }
1264  else
1265  {
1266  $question_text .= '[gap ' . $i . $part;
1267  }
1268  $i++;
1269  }
1270  return $question_text;
1271  }
1272 
1273  public function removeIndizesFromGapText( $question_text )
1274  {
1275  $parts = preg_split( '/\[gap \d*\]/', $question_text );
1276  $question_text = implode( '[gap]', $parts );
1277  return $question_text;
1278  }
1279 
1290  {
1291  return array();
1292  }
1293 
1304  {
1305  return array('fixedTextLength');
1306  }
1307 
1308  public function resetFormValuesForSuppressedPostvars(ilPropertyFormGUI $form)
1309  {
1310  $gapindex = 0;
1311  while($element = $form->getItemByPostVar('gap['.$gapindex.']'))
1312  {
1313  $type_selector = $form->getItemByPostVar('clozetype_'.$gapindex);
1314  $value = $type_selector->getValue();
1315 
1316  if($value == CLOZE_SELECT)
1317  {
1319  $the_gap = $this->object->getGap($gapindex);
1320  foreach($the_gap->getItemsRaw() as $itemindex => $answer_cloze)
1321  {
1322  $_POST['gap_'.$gapindex]['answer'][$itemindex] = $answer_cloze->getAnswertext();
1323  }
1325  $element = $form->getItemByPostVar('gap_'.$gapindex);
1326  $element->setValues($the_gap->getItemsRaw());
1327 
1329  $element = $form->getItemByPostVar('shuffle_'.$gapindex);
1330  $element->setChecked($the_gap->getShuffle());
1331  }
1332  $gapindex++;
1333  }
1334  }
1335 
1336  public function getAggregatedAnswersView($relevant_answers)
1337  {
1338  $passes = array();
1339  foreach($relevant_answers as $pass)
1340  {
1341  $passes[$pass['active_fi'].'-'.$pass['pass']] = '-';
1342  }
1343  $passcount = count($passes);
1344 
1345  foreach($relevant_answers as $pass)
1346  {
1347  $actives[$pass['active_fi']] = $pass['active_fi'];
1348  }
1349  $usercount = count($actives);
1350  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_header.html', true, true, "Modules/TestQuestionPool");
1351  $tpl->setVariable('HEADERTEXT', $this->lng->txt('overview'));
1352  $tpl->setVariable('NUMBER_OF_USERS_INFO', $this->lng->txt('number_of_users'));
1353  $tpl->setVariable('NUMBER_OF_USERS', $usercount);
1354  $tpl->setVariable('NUMBER_OF_PASSES_INFO', $this->lng->txt('number_of_passes'));
1355  $tpl->setVariable('NUMBER_OF_PASSES', $passcount);
1356 
1357  return $tpl->get() . $this->renderAggregateView( $this->aggregateAnswers($relevant_answers) );
1358  }
1359 
1360  public function aggregateAnswers($relevant_answers_chosen)
1361  {
1362  $gaps = array();
1363 
1364  foreach($relevant_answers_chosen as $answer)
1365  {
1366  $gaps[$answer['value1']][] = $answer;
1367  }
1368 
1369  return $gaps;
1370  }
1371 
1377  public function renderAggregateView($aggregate)
1378  {
1379  $html = '';
1380  foreach($aggregate as $index => $gap)
1381  {
1382  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
1383  $tpl->setVariable( 'OPTION_HEADER', $this->lng->txt('answer') );
1384  $tpl->setVariable( 'COUNT_HEADER', $this->lng->txt('count') );
1385 
1386  $current_gap_definition = $this->object->getGap($index);
1387  switch ($current_gap_definition->getType())
1388  {
1389  case CLOZE_TEXT:
1390  $gaptype = $this->lng->txt('text_gap');
1391  $tpl = $this->getTextGapAggregation($index, $tpl, $gap);
1392  break;
1393  case CLOZE_SELECT:
1394  $gaptype = $this->lng->txt('select_gap');
1395  $tpl = $this->getSelectGapAggregation($tpl, $gap);
1396  break;
1397  case CLOZE_NUMERIC:
1398  $gaptype = $this->lng->txt('numeric_gap');
1399  $tpl = $this->getNumericGapAggregation($tpl, $gap);
1400  break;
1401  }
1402  $tpl->setVariable( 'AGGREGATION_HEADER',
1403  $this->lng->txt('gap')
1404  . '&nbsp;' . ($index+1)
1405  . '&nbsp;<small>(' . $gaptype . ')</small>');
1406  $html .= $tpl->get();
1407  }
1408 
1409  return $html;
1410  }
1411 
1412  public function getTextGapAggregation($index, $tpl, $gap_answers)
1413  {
1414  $the_gap = $this->object->getGap($gap_answers[0]['value1']);
1415  foreach($the_gap->getItems() as $answer)
1416  {
1417  $answer_texts[] = $answer->getAnswertext();
1418  }
1419  $gapdata = array();
1420  foreach($gap_answers as $answer)
1421  {
1422  if(isset($gapdata[$answer['value2']]))
1423  {
1424  $gapdata[$answer['value2']]++;
1425  } else {
1426  $gapdata[$answer['value2']] = 1;
1427  }
1428  }
1429  $temp_counter = 0;
1430  foreach($gapdata as $answer => $count)
1431  {
1432  $tpl->setCurrentBlock( 'aggregaterow' );
1433  $tpl->setVariable( 'OPTION', '<p id="text_answer_' . $index . '_' . $temp_counter . '">' . $answer . '</p>');
1434  if(!in_array($answer, $answer_texts))
1435  {
1436  $tpl->setVariable( 'ACTION', '<input class="add_correction_answer submit" for="text_answer_' . $index .
1437  '_' . $temp_counter . '" name="' . $index . '" value="Add"/>' );
1438  $tpl->setVariable( 'POINTS', '<input type="text" id="text_points_' . $index . '_' . $temp_counter . '" value="0"/>' );
1439  }
1440  $tpl->setVariable( 'COUNT', $count );
1441  $tpl->parseCurrentBlock();
1442  $temp_counter ++;
1443  }
1444  $tpl->touchBlock('js_cloze');
1445  return $tpl;
1446  }
1447 
1448  public function getSelectGapAggregation($tpl, $gap)
1449  {
1450  $gapdata = array();
1451  foreach($gap as $answer)
1452  {
1453  $current_gap = $this->object->getGap($answer['value1']);
1454  $items=$current_gap->getItemsRaw();
1455  $item = $items[$answer['value2']];
1456  $text = $item->getAnswertext();
1457  if(isset($gapdata[$text]))
1458  {
1459  $gapdata[$text]++;
1460  } else {
1461  $gapdata[$text] = 1;
1462  }
1463  }
1464 
1465  foreach($gapdata as $answer => $count)
1466  {
1467  $tpl->setCurrentBlock( 'aggregaterow' );
1468  $tpl->setVariable( 'OPTION', $answer );
1469  $tpl->setVariable( 'COUNT', $count );
1470  $tpl->parseCurrentBlock();
1471  }
1472  return $tpl;
1473  }
1474 
1475  public function getNumericGapAggregation($tpl, $gap)
1476  {
1477  $gapdata = array();
1478  foreach($gap as $answer)
1479  {
1480  if(isset($gapdata[$answer['value2']]))
1481  {
1482  $gapdata[$answer['value2']]++;
1483  } else {
1484  $gapdata[$answer['value2']] = 1;
1485  }
1486  }
1487 
1488  foreach($gapdata as $answer => $count)
1489  {
1490  $tpl->setCurrentBlock( 'aggregaterow' );
1491  $tpl->setVariable( 'OPTION', $answer );
1492  $tpl->setVariable( 'COUNT', $count );
1493  $tpl->parseCurrentBlock();
1494  }
1495  return $tpl;
1496  }
1497 
1499  {
1500  $gapindex = 0;
1501  while($element = $form->getItemByPostVar('gap['.$gapindex.']'))
1502  {
1503  $type_selector = $form->getItemByPostVar('clozetype_'.$gapindex);
1504  $type_selector->setDisabled(true);
1505  $value = $type_selector->getValue();
1506  switch ($value)
1507  {
1508  case CLOZE_TEXT:
1509  break;
1510  case CLOZE_SELECT:
1511  $this->disableSelectGapFields($form, $gapindex);
1512  case CLOZE_NUMERIC:
1513  }
1514  $gapindex++;
1515  }
1516 
1517  return $form;
1518  }
1519 
1520  public function disableSelectGapFields($form, $gapindex)
1521  {
1522  $element = $form->getItemByPostvar('gap_'.$gapindex);
1523  $element->setDisableActions(true);
1524  $element->setDisableText(true);
1525 
1527  $element = $form->getItemByPostvar('shuffle_'.$gapindex);
1528  $element->setDisabled(true);
1529  }
1530 }