ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assTextQuestionGUI.php
Go to the documentation of this file.
1 <?php
2  /*
3  +----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +----------------------------------------------------------------------------+
22 */
23 
24 include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
25 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
26 
39 {
48  function __construct($id = -1)
49  {
51  include_once "./Modules/TestQuestionPool/classes/class.assTextQuestion.php";
52  $this->object = new assTextQuestion();
53  if ($id >= 0)
54  {
55  $this->object->loadFromDb($id);
56  }
57  }
58 
65  function writePostData($always = false)
66  {
67  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
68  if (!$hasErrors)
69  {
70  $this->object->setTitle($_POST["title"]);
71  $this->object->setAuthor($_POST["author"]);
72  $this->object->setComment($_POST["comment"]);
73  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
74  $questiontext = $_POST["question"];
75  $this->object->setQuestion($questiontext);
76  $this->object->setMaxNumOfChars($_POST["maxchars"]);
77  $this->object->setTextRating($_POST["text_rating"]);
78  if ($this->getSelfAssessmentEditingMode())
79  {
80  $this->object->setNrOfTries($_POST['nr_of_tries']);
81  }
82  $this->object->setEstimatedWorkingTime(
83  $_POST["Estimated"]["hh"],
84  $_POST["Estimated"]["mm"],
85  $_POST["Estimated"]["ss"]
86  );
87  $this->object->setKeywordRelation($_POST['scoring_mode']);
88 
89  switch( $this->object->getKeywordRelation() )
90  {
91 
92  case 'non':
93 
94  $this->object->setAnswers(array());
95  $this->object->setPoints($_POST['non_keyword_points']);
96  break;
97 
98  case 'any':
99 
100  $this->object->setAnswers($_POST['any_keyword']);
101  $this->object->setPoints($this->object->getMaximumPoints());
102  break;
103 
104  case 'all':
105  $this->object->setAnswers($_POST['all_keyword']);
106  $this->object->setPoints($_POST['all_keyword_points']);
107  break;
108 
109  case 'one':
110 
111  $this->object->setAnswers($_POST['one_keyword']);
112  $this->object->setPoints($_POST['one_keyword_points']);
113  break;
114  }
115 
116  return 0;
117  }
118  else
119  {
120  return 1;
121  }
122  }
123 
129  public function editQuestion($checkonly = FALSE)
130  {
131  $save = $this->isSaveCommand();
132  $this->getQuestionTemplate();
133 
134  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
135  $form = new ilPropertyFormGUI();
136  $form->setFormAction($this->ctrl->getFormAction($this));
137  $form->setTitle($this->outQuestionType());
138  $form->setMultipart(TRUE);
139  $form->setTableWidth("100%");
140  $form->setId("asstextquestion");
141 
142  // title, author, description, question, working time (assessment mode)
143  $this->addBasicQuestionFormProperties($form);
144 
145  // maxchars
146  $maxchars = new ilNumberInputGUI($this->lng->txt("maxchars"), "maxchars");
147  $maxchars->setSize(5);
148  if ($this->object->getMaxNumOfChars() > 0) $maxchars->setValue($this->object->getMaxNumOfChars());
149  $maxchars->setInfo($this->lng->txt("description_maxchars"));
150  $form->addItem($maxchars);
151 
152  // text rating
153  $textrating = new ilSelectInputGUI($this->lng->txt("text_rating"), "text_rating");
154  $text_options = array(
155  "ci" => $this->lng->txt("cloze_textgap_case_insensitive"),
156  "cs" => $this->lng->txt("cloze_textgap_case_sensitive"),
157  "l1" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "1"),
158  "l2" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "2"),
159  "l3" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "3"),
160  "l4" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "4"),
161  "l5" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "5")
162  );
163  $textrating->setOptions($text_options);
164  $textrating->setValue($this->object->getTextRating());
165  $form->addItem($textrating);
166 
167  if (!$this->getSelfAssessmentEditingMode())
168  {
169  if( $this->object->getAnswerCount() == 0 )
170  {
171  $this->object->addAnswer("", 1, 0, 0);
172  }
173 
174  $scoringMode = new ilRadioGroupInputGUI(
175  $this->lng->txt('essay_scoring_mode'), 'scoring_mode'
176  );
177 
178  $scoringOptionNone = new ilRadioOption( $this->lng->txt('essay_scoring_mode_without_keywords'),
179  'non', $this->lng->txt('essay_scoring_mode_without_keywords_desc')
180  );
181  $scoringOptionAnyKeyword = new ilRadioOption( $this->lng->txt('essay_scoring_mode_keyword_relation_any'),
182  'any', $this->lng->txt('essay_scoring_mode_keyword_relation_any_desc')
183  );
184  $scoringOptionAllKeyword = new ilRadioOption( $this->lng->txt('essay_scoring_mode_keyword_relation_all'),
185  'all', $this->lng->txt('essay_scoring_mode_keyword_relation_all_desc')
186  );
187  $scoringOptionOneKeyword = new ilRadioOption( $this->lng->txt('essay_scoring_mode_keyword_relation_one'),
188  'one', $this->lng->txt('essay_scoring_mode_keyword_relation_one_desc')
189  );
190 
191  $scoringMode->addOption($scoringOptionNone);
192  $scoringMode->addOption($scoringOptionAnyKeyword);
193  $scoringMode->addOption($scoringOptionAllKeyword);
194  $scoringMode->addOption($scoringOptionOneKeyword);
195  $scoringMode->setRequired(true);
196  $scoringMode->setValue(strlen($this->object->getKeywordRelation()) ? $this->object->getKeywordRelation() : 'non');
197 
198  require_once "./Modules/TestQuestionPool/classes/class.ilEssayKeywordWizardInputGUI.php";
199 
200  // Without Keywords
201  $nonKeywordPoints = new ilNumberInputGUI($this->lng->txt("points"), "non_keyword_points");
202  $nonKeywordPoints->setValue($this->object->getPoints());
203  $nonKeywordPoints->setRequired(TRUE);
204  $nonKeywordPoints->setSize(3);
205  $nonKeywordPoints->setMinValue(0.0);
206  $nonKeywordPoints->setMinvalueShouldBeGreater(true);
207  $scoringOptionNone->addSubItem($nonKeywordPoints);
208 
209  // Any Keyword
210  $anyKeyword = new ilEssayKeywordWizardInputGUI($this->lng->txt("answers"), "any_keyword");
211  $anyKeyword->setRequired(TRUE);
212  $anyKeyword->setQuestionObject($this->object);
213  $anyKeyword->setSingleline(TRUE);
214  $anyKeyword->setValues($this->object->getAnswers());
215  $scoringOptionAnyKeyword->addSubItem($anyKeyword);
216 
217  // All Keywords
218  $allKeyword = new ilTextWizardInputGUI($this->lng->txt("answers"), "all_keyword");
219  $allKeyword->setRequired(TRUE);
220  //$allKeyword->setQuestionObject($this->object);
221  //$allKeyword->setSingleline(TRUE);
222  $allKeyword->setValues(self::buildAnswerTextOnlyArray($this->object->getAnswers()));
223  $scoringOptionAllKeyword->addSubItem($allKeyword);
224  $allKeywordPoints = new ilNumberInputGUI($this->lng->txt("points"), "all_keyword_points");
225  $allKeywordPoints->setValue($this->object->getPoints());
226  $allKeywordPoints->setRequired(TRUE);
227  $allKeywordPoints->setSize(3);
228  $allKeywordPoints->setMinValue(0.0);
229  $allKeywordPoints->setMinvalueShouldBeGreater(true);
230  $scoringOptionAllKeyword->addSubItem($allKeywordPoints);
231 
232  // One Keywords
233  $oneKeyword = new ilTextWizardInputGUI($this->lng->txt("answers"), "one_keyword");
234  $oneKeyword->setRequired(TRUE);
235  //$oneKeyword->setQuestionObject($this->object);
236  //$oneKeyword->setSingleline(TRUE);
237  $oneKeyword->setValues(self::buildAnswerTextOnlyArray($this->object->getAnswers()));
238  $scoringOptionOneKeyword->addSubItem($oneKeyword);
239  $oneKeywordPoints = new ilNumberInputGUI($this->lng->txt("points"), "one_keyword_points");
240  $oneKeywordPoints->setValue($this->object->getPoints());
241  $oneKeywordPoints->setRequired(TRUE);
242  $oneKeywordPoints->setSize(3);
243  $oneKeywordPoints->setMinValue(0.0);
244  $oneKeywordPoints->setMinvalueShouldBeGreater(true);
245  $scoringOptionOneKeyword->addSubItem($oneKeywordPoints);
246 
247  $form->addItem($scoringMode);
248  }
249 
250  $this->addQuestionFormCommandButtons($form);
251  $errors = false;
252 
253  if ($save)
254  {
255  $form->setValuesByPost();
256  $errors = !$form->checkInput();
257  $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we need this if we don't want to have duplication of backslashes
258  if ($errors) $checkonly = false;
259  }
260 
261  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
262  return $errors;
263  }
264 
265  private static function buildAnswerTextOnlyArray($answers)
266  {
267  $answerTexts = array();
268 
269  foreach($answers as $answer)
270  {
271  $answerTexts[] = $answer->answertext;
272  }
273 
274  return $answerTexts;
275  }
276 
278  {
279  if ($this->object->getMaxNumOfChars() > 0)
280  {
281  $this->tpl->addBlockFile("CONTENT_BLOCK", "charcounter", "tpl.charcounter.html", "Modules/TestQuestionPool");
282  $this->tpl->setCurrentBlock("charcounter");
283  $this->tpl->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
284  $this->tpl->parseCurrentBlock();
285  }
286  }
287 
288  function outQuestionForTest($formaction, $active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
289  {
290  $test_output = $this->getTestOutput($active_id, $pass, $is_postponed, $use_post_solutions);
291  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
292  $this->tpl->setVariable("FORMACTION", $formaction);
293  include_once "./Services/RTE/classes/class.ilRTE.php";
294  $rtestring = ilRTE::_getRTEClassname();
295  include_once "./Services/RTE/classes/class.$rtestring.php";
296  $rte = new $rtestring('3.4.7');
297  include_once "./Services/Object/classes/class.ilObject.php";
298  $obj_id = ilObject::_lookupObjectId($_GET["ref_id"]);
299  $obj_type = ilObject::_lookupType($_GET["ref_id"], TRUE);
300  $rte->addUserTextEditor("textinput");
301  $this->outAdditionalOutput();
302  }
303 
318  $active_id,
319  $pass = NULL,
320  $graphicalOutput = FALSE,
321  $result_output = FALSE,
322  $show_question_only = TRUE,
323  $show_feedback = FALSE,
324  $show_correct_solution = FALSE,
325  $show_manual_scoring = FALSE,
326  $show_question_text = TRUE
327  )
328  {
329  // get the solution of the user for the active pass or from the last pass if allowed
330 
331  if (($active_id > 0) && (!$show_correct_solution))
332  {
333  $solution = $this->getUserAnswer( $active_id, $pass );
334  }
335  else
336  {
337  $solution = $this->getBestAnswer();
338  }
339  $user_solution = $this->getUserAnswer( $active_id, $pass );
340 
341  // generate the question output
342  include_once "./Services/UICore/classes/class.ilTemplate.php";
343  $template = new ilTemplate("tpl.il_as_qpl_text_question_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
344  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
345 
346  $solution = $this->object->getHtmlUserSolutionPurifier()->purify($solution);
347 
348  $template->setVariable("ESSAY", $this->object->prepareTextareaOutput($solution, TRUE));
349  $questiontext = $this->object->getQuestion();
350 
351  if (!$show_correct_solution)
352  {
353  $max_no_of_chars = $this->object->getMaxNumOfChars();
354 
355  if ($max_no_of_chars == 0)
356  {
357  $max_no_of_chars = ucfirst($this->lng->txt('unlimited'));
358  }
359 
360  $act_no_of_chars = strlen(strip_tags($user_solution));
361  $template->setVariable("CHARACTER_INFO", '<b>' . $max_no_of_chars . '</b>' .
362  $this->lng->txt('answer_characters') . ' <b>' . $act_no_of_chars . '</b>');
363  }
364  if (($active_id > 0) && (!$show_correct_solution))
365  {
366  if ($graphicalOutput)
367  {
368  // output of ok/not ok icons for user entered solutions
369  $reached_points = $this->object->getReachedPoints($active_id, $pass);
370  if ($reached_points == $this->object->getMaximumPoints())
371  {
372  $template->setCurrentBlock("icon_ok");
373  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.png"));
374  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
375  $template->parseCurrentBlock();
376  }
377  else
378  {
379  $template->setCurrentBlock("icon_ok");
380  if ($reached_points > 0)
381  {
382  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.png"));
383  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
384  }
385  else
386  {
387  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.png"));
388  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
389  }
390  $template->parseCurrentBlock();
391  }
392  }
393  }
394  if ($show_question_text==true)
395  {
396  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
397  }
398  $questionoutput = $template->get();
399 
400  $feedback = '';
401  if($show_feedback)
402  {
403  $fb = $this->getGenericFeedbackOutput($active_id, $pass);
404  $feedback .= strlen($fb) ? $fb : '';
405 
406  $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
407  $feedback .= strlen($fb) ? $fb : '';
408  }
409  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
410 
411  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
412 
413  $solutionoutput = $solutiontemplate->get();
414  if (!$show_question_only)
415  {
416  // get page object output
417  $solutionoutput = '<div class="ilc_question_Standard">'.$solutionoutput."</div>";
418  }
419  return $solutionoutput;
420  }
421 
422  private function getBestAnswer()
423  {
424  $answers = $this->object->getAnswers();
425  if (count( $answers ))
426  {
427  $user_solution = $this->lng->txt( "solution_contain_keywords" ) . "<ul>";
428 
429  foreach ($answers as $answer)
430  {
431  $user_solution .= '<li>'. $answer->getAnswertext();
432 
433  if( in_array($this->object->getKeywordRelation(), assTextQuestion::getScoringModesWithPointsByKeyword()) )
434  {
435  $user_solution .= ' ' . $this->lng->txt('for') . ' ';
436  $user_solution .= $answer->getPoints() . ' ' . $this->lng->txt('points') . '</li>';
437  }
438  }
439  $user_solution .= '</ul>';
440 
441  $user_solution .= $this->lng->txt('essay_scoring_mode') . ': ';
442 
443  switch( $this->object->getKeywordRelation() )
444  {
445  case 'any':
446  $user_solution .= $this->lng->txt('essay_scoring_mode_keyword_relation_any');
447  break;
448  case 'all':
449  $user_solution .= $this->lng->txt('essay_scoring_mode_keyword_relation_all');
450  break;
451  case 'one':
452  $user_solution .= $this->lng->txt('essay_scoring_mode_keyword_relation_one');
453  break;
454  }
455  }
456  return $user_solution;
457  }
458 
459  private function getUserAnswer($active_id, $pass)
460  {
461  $user_solution = "";
462  $solutions = $this->object->getSolutionValues( $active_id, $pass );
463  foreach ($solutions as $idx => $solution_value)
464  {
465  $user_solution = $solution_value["value1"];
466  }
467  return $user_solution;
468  }
469 
470  function getPreview($show_question_only = FALSE)
471  {
472  // generate the question output
473  include_once "./Services/UICore/classes/class.ilTemplate.php";
474  $template = new ilTemplate("tpl.il_as_qpl_text_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
475  if ($this->object->getMaxNumOfChars())
476  {
477  $template->setCurrentBlock("maximum_char_hint");
478  $template->setVariable("MAXIMUM_CHAR_HINT", sprintf($this->lng->txt("text_maximum_chars_allowed"), $this->object->getMaxNumOfChars()));
479  $template->parseCurrentBlock();
480  #mbecker: No such block. $template->setCurrentBlock("has_maxchars");
481  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
482  $template->parseCurrentBlock();
483  $template->setCurrentBlock("maxchars_counter");
484  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
485  $template->setVariable("TEXTBOXSIZE", strlen($this->object->getMaxNumOfChars()));
486  $template->setVariable("CHARACTERS", $this->lng->txt("characters"));
487  $template->parseCurrentBlock();
488  }
489  $questiontext = $this->object->getQuestion();
490  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
491  $questionoutput = $template->get();
492  if (!$show_question_only)
493  {
494  // get page object output
495  $questionoutput = $this->getILIASPage($questionoutput);
496  }
497  return $questionoutput;
498  }
499 
500  function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
501  {
502  // get the solution of the user for the active pass or from the last pass if allowed
503  $user_solution = "";
504  if ($active_id)
505  {
506  $solutions = NULL;
507  include_once "./Modules/Test/classes/class.ilObjTest.php";
508  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
509  {
510  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
511  }
512  $solutions =& $this->object->getSolutionValues($active_id, $pass);
513  foreach ($solutions as $idx => $solution_value)
514  {
515  $user_solution = $solution_value["value1"];
516  }
517  }
518 
519  // generate the question output
520  include_once "./Services/UICore/classes/class.ilTemplate.php";
521  $template = new ilTemplate("tpl.il_as_qpl_text_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
522  if ($this->object->getMaxNumOfChars())
523  {
524  $template->setCurrentBlock("maximum_char_hint");
525  $template->setVariable("MAXIMUM_CHAR_HINT", sprintf($this->lng->txt("text_maximum_chars_allowed"), $this->object->getMaxNumOfChars()));
526  $template->parseCurrentBlock();
527  #mbecker: No such block. $template->setCurrentBlock("has_maxchars");
528  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
529  $template->parseCurrentBlock();
530  $template->setCurrentBlock("maxchars_counter");
531  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
532  $template->setVariable("TEXTBOXSIZE", strlen($this->object->getMaxNumOfChars()));
533  $template->setVariable("CHARACTERS", $this->lng->txt("characters"));
534  $template->parseCurrentBlock();
535  }
536  $template->setVariable("ESSAY", ilUtil::prepareFormOutput($user_solution));
537  $questiontext = $this->object->getQuestion();
538  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
539  $questionoutput = $template->get();
540  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
541  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
543  return $pageoutput;
544  }
545 
547  {
548  $_SESSION["subquestion_index"] = 0;
549  if ($_POST["cmd"]["addSuggestedSolution"])
550  {
551  if ($this->writePostData())
552  {
554  $this->editQuestion();
555  return;
556  }
557  if (!$this->checkInput())
558  {
559  ilUtil::sendInfo($this->lng->txt("fill_out_all_required_fields_add_answer"));
560  $this->editQuestion();
561  return;
562  }
563  }
564  $this->object->saveToDb();
565  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
566  $this->tpl->setVariable("HEADER", $this->object->getTitle());
567  $this->getQuestionTemplate();
569  }
570 
576  function saveFeedback()
577  {
578  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
579  $errors = $this->feedback(true);
580  $this->object->saveFeedbackGeneric(0, $_POST["feedback_incomplete"]);
581  $this->object->saveFeedbackGeneric(1, $_POST["feedback_complete"]);
582  foreach ($this->object->getAnswers() as $index => $answer)
583  {
584  $this->object->saveFeedbackSingleAnswer($index, $_POST["feedback_answer_$index"]);
585  }
586 
587  $this->object->cleanupMediaObjectUsage();
589  }
590 
598  function setQuestionTabs()
599  {
600  global $rbacsystem, $ilTabs;
601 
602  $this->ctrl->setParameterByClass("ilpageobjectgui", "q_id", $_GET["q_id"]);
603  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
604  $q_type = $this->object->getQuestionType();
605 
606  if (strlen($q_type))
607  {
608  $classname = $q_type . "GUI";
609  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
610  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
611  }
612 
613  if ($_GET["q_id"])
614  {
615  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
616  {
617  // edit page
618  $ilTabs->addTarget("edit_page",
619  $this->ctrl->getLinkTargetByClass("ilPageObjectGUI", "edit"),
620  array("edit", "insert", "exec_pg"),
621  "", "", $force_active);
622  }
623 
624  // edit page
625  $ilTabs->addTarget("preview",
626  $this->ctrl->getLinkTargetByClass("ilPageObjectGUI", "preview"),
627  array("preview"),
628  "ilPageObjectGUI", "", $force_active);
629  }
630 
631  $force_active = false;
632  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
633  {
634  $url = "";
635  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
636  // edit question properties
637  $ilTabs->addTarget("edit_question",
638  $url,
639  array("editQuestion", "save", "saveEdit", "originalSyncForm"),
640  $classname, "", $force_active);
641  }
642 
643  if ($_GET["q_id"])
644  {
645  $ilTabs->addTarget("feedback",
646  $this->ctrl->getLinkTargetByClass($classname, "feedback"),
647  array("feedback", "saveFeedback"),
648  $classname, "");
649  }
650 
651  // add tab for question hint within common class assQuestionGUI
652  $this->addTab_QuestionHints($ilTabs);
653 
654  if ($_GET["q_id"])
655  {
656  $ilTabs->addTarget("solution_hint",
657  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
658  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
659  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
660  ),
661  $classname,
662  ""
663  );
664  }
665 
666  // Assessment of questions sub menu entry
667  if ($_GET["q_id"])
668  {
669  $ilTabs->addTarget("statistics",
670  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
671  array("assessment"),
672  $classname, "");
673  }
674 
675  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
676  {
677  $ref_id = $_GET["calling_test"];
678  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
679 
680  global $___test_express_mode;
681 
682  if (!$_GET['test_express_mode'] && !$___test_express_mode) {
683  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
684  }
685  else {
687  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
688  }
689  }
690  else
691  {
692  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
693  }
694  }
695 
696  function getSpecificFeedbackOutput($active_id, $pass)
697  {
698  $feedback = '<table><tbody>';
699  $user_answers = $this->object->getSolutionValues($active_id);
700  $user_answer = ' '. $user_answers[0]['value1'];
701 
702  foreach ($this->object->getAnswers() as $idx => $ans)
703  {
704  if ($this->object->isKeywordMatching($user_answer, $ans->getAnswertext() ))
705  {
706  $feedback .= '<tr><td><b><i>' . $ans->getAnswertext() . '</i></b></td><td>';
707  $feedback .= $this->object->getFeedbackSingleAnswer($idx) . '</td> </tr>';
708  }
709  }
710 
711  $feedback .= '</tbody></table>';
712  return $this->object->prepareTextareaOutput($feedback, TRUE);
713  }
719  function feedback($checkonly = false)
720  {
721  $save = (strcmp($this->ctrl->getCmd(), "saveFeedback") == 0) ? TRUE : FALSE;
722  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
723  $form = new ilPropertyFormGUI();
724  $form->setFormAction($this->ctrl->getFormAction($this));
725  $form->setTitle($this->lng->txt('feedback_answers'));
726  $form->setTableWidth("98%");
727  $form->setId("feedback");
728 
729  $complete = new ilTextAreaInputGUI($this->lng->txt("feedback_complete_solution"), "feedback_complete");
730  $complete->setValue($this->object->prepareTextareaOutput($this->object->getFeedbackGeneric(1)));
731  $complete->setRequired(false);
732  $complete->setRows(10);
733  $complete->setCols(80);
734  if (!$this->getPreventRteUsage())
735  {
736  $complete->setUseRte(true);
737  }
738  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
739  $complete->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
740  $complete->addPlugin("latex");
741  $complete->addButton("latex");
742  $complete->addButton("pastelatex");
743  $complete->setRTESupport($this->object->getId(), "qpl", "assessment", null, false, '3.4.7');
744  $form->addItem($complete);
745 
746  $incomplete = new ilTextAreaInputGUI($this->lng->txt("feedback_incomplete_solution"), "feedback_incomplete");
747  $incomplete->setValue($this->object->prepareTextareaOutput($this->object->getFeedbackGeneric(0)));
748  $incomplete->setRequired(false);
749  $incomplete->setRows(10);
750  $incomplete->setCols(80);
751  if (!$this->getPreventRteUsage())
752  {
753  $incomplete->setUseRte(true);
754  }
755  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
756  $incomplete->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
757  $incomplete->addPlugin("latex");
758  $incomplete->addButton("latex");
759  $incomplete->addButton("pastelatex");
760  $incomplete->setRTESupport($this->object->getId(), "qpl", "assessment", null, false, '3.4.7');
761  $form->addItem($incomplete);
762 
763  if (!$this->getSelfAssessmentEditingMode())
764  {
765  foreach ($this->object->getAnswers() as $index => $answer)
766  {
767  $caption = $ordinal = $index+1;
768  $caption .= '. ' . $answer->getAnswertext();
769 
770  $answerobj = new ilTextAreaInputGUI($this->object->prepareTextareaOutput($caption, true), "feedback_answer_$index");
771  $answerobj->setValue($this->object->prepareTextareaOutput($this->object->getFeedbackSingleAnswer($index)));
772  $answerobj->setRequired(false);
773  $answerobj->setRows(10);
774  $answerobj->setCols(80);
775  $answerobj->setUseRte(true);
776  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
777  $answerobj->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
778  $answerobj->addPlugin("latex");
779  $answerobj->addButton("latex");
780  $answerobj->addButton("pastelatex");
781  $answerobj->setRTESupport($this->object->getId(), "qpl", "assessment", null, false, '3.4.7');
782  $form->addItem($answerobj);
783  }
784  }
785 
786  global $ilAccess;
787  if ($ilAccess->checkAccess("write", "", $_GET['ref_id']) || $this->getSelfAssessmentEditingMode())
788  {
789  $form->addCommandButton("saveFeedback", $this->lng->txt("save"));
790  }
791  if ($save)
792  {
793  $form->setValuesByPost();
794  $errors = !$form->checkInput();
795  $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we need this if we don't want to have duplication of backslashes
796  }
797  if (!$checkonly) $this->tpl->setVariable("ADM_CONTENT", $form->getHTML());
798  return $errors;
799  }
800 }