ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assTextSubsetGUI.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.assTextSubset.php";
52  $this->object = new assTextSubset();
53  if ($id >= 0)
54  {
55  $this->object->loadFromDb($id);
56  }
57  }
58 
59  function getCommand($cmd)
60  {
61  return $cmd;
62  }
63 
70  function writePostData($always = false)
71  {
72  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
73  if (!$hasErrors)
74  {
75  $this->object->setTitle($_POST["title"]);
76  $this->object->setAuthor($_POST["author"]);
77  $this->object->setComment($_POST["comment"]);
78  if ($this->getSelfAssessmentEditingMode())
79  {
80  $this->object->setNrOfTries($_POST['nr_of_tries']);
81  }
82 
83  // mbecker: fix for 8407
84  $this->object->setEstimatedWorkingTime(
85  $_POST["Estimated"]["hh"],
86  $_POST["Estimated"]["mm"],
87  $_POST["Estimated"]["ss"]
88  );
89  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
90  $questiontext = $_POST["question"];
91  $this->object->setQuestion($questiontext);
92  $this->object->setCorrectAnswers($_POST["correctanswers"]);
93  $this->object->setTextRating($_POST["text_rating"]);
94  // Delete all existing answers and create new answers from the form data
95  $this->object->flushAnswers();
96  foreach ($_POST['answers']['answer'] as $index => $answer)
97  {
98  $answertext = $answer;
99  $this->object->addAnswer($answertext, $_POST['answers']['points'][$index], $index);
100  }
101  return 0;
102  }
103  else
104  {
105  return 1;
106  }
107  }
108 
114  public function editQuestion($checkonly = FALSE)
115  {
116  $save = $this->isSaveCommand();
117  $this->getQuestionTemplate();
118 
119  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
120  $form = new ilPropertyFormGUI();
121  $form->setFormAction($this->ctrl->getFormAction($this));
122  $form->setTitle($this->outQuestionType());
123  $form->setMultipart(FALSE);
124  $form->setTableWidth("100%");
125  $form->setId("asstextsubset");
126 
127  $this->addBasicQuestionFormProperties($form);
128 
129  // number of requested answers
130  $correctanswers = new ilNumberInputGUI($this->lng->txt("nr_of_correct_answers"), "correctanswers");
131  $correctanswers->setMinValue(1);
132  $correctanswers->setDecimals(0);
133  $correctanswers->setSize(3);
134  $correctanswers->setValue($this->object->getCorrectAnswers());
135  $correctanswers->setRequired(true);
136  $form->addItem($correctanswers);
137 
138  // maximum available points
139  $points = new ilNumberInputGUI($this->lng->txt("maximum_points"), "points");
140  $points->setMinValue(0.0);
141  $points->setMinvalueShouldBeGreater(true);
142  $points->setSize(6);
143  $points->setDisabled(true);
144  $points->setValue($this->object->getMaximumPoints());
145  $points->setRequired(false);
146  $form->addItem($points);
147 
148  // text rating
149  $textrating = new ilSelectInputGUI($this->lng->txt("text_rating"), "text_rating");
150  $text_options = array(
151  "ci" => $this->lng->txt("cloze_textgap_case_insensitive"),
152  "cs" => $this->lng->txt("cloze_textgap_case_sensitive")
153  );
154  if (!$this->getSelfAssessmentEditingMode())
155  {
156  $text_options["l1"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "1");
157  $text_options["l2"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "2");
158  $text_options["l3"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "3");
159  $text_options["l4"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "4");
160  $text_options["l5"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "5");
161  }
162  $textrating->setOptions($text_options);
163  $textrating->setValue($this->object->getTextRating());
164  $form->addItem($textrating);
165 
166  // Choices
167  include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
168  $choices = new ilAnswerWizardInputGUI($this->lng->txt("answers"), "answers");
169  $choices->setRequired(true);
170  $choices->setQuestionObject($this->object);
171  $choices->setSingleline(true);
172  $choices->setAllowMove(false);
173  $choices->setMinValue(0.0);
174  if ($this->object->getAnswerCount() == 0) $this->object->addAnswer("", 0, 0);
175  $choices->setValues($this->object->getAnswers());
176  $form->addItem($choices);
177 
178  $this->addQuestionFormCommandButtons($form);
179 
180  $errors = false;
181 
182  if ($save)
183  {
184  $form->setValuesByPost();
185  $points->setValue($this->object->getMaximumPoints());
186  $errors = !$form->checkInput();
187  $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
188  if ($errors) $checkonly = false;
189  }
190 
191  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
192  return $errors;
193  }
194 
198  public function addanswers()
199  {
200  $this->writePostData(true);
201  $position = key($_POST['cmd']['addanswers']);
202  $this->object->addAnswer("", 0, $position+1);
203  $this->editQuestion();
204  }
205 
209  public function removeanswers()
210  {
211  $this->writePostData(true);
212  $position = key($_POST['cmd']['removeanswers']);
213  $this->object->deleteAnswer($position);
214  $this->editQuestion();
215  }
216 
217  function outQuestionForTest($formaction, $active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
218  {
219  $test_output = $this->getTestOutput($active_id, $pass, $is_postponed, $use_post_solutions);
220  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
221  $this->tpl->setVariable("FORMACTION", $formaction);
222  }
223 
238  $active_id,
239  $pass = NULL,
240  $graphicalOutput = FALSE,
241  $result_output = FALSE,
242  $show_question_only = TRUE,
243  $show_feedback = FALSE,
244  $show_correct_solution = FALSE,
245  $show_manual_scoring = FALSE,
246  $show_question_text = TRUE
247  )
248  {
249  // get the solution of the user for the active pass or from the last pass if allowed
250  $solutions = array();
251  if (($active_id > 0) && (!$show_correct_solution))
252  {
253  $solutions =& $this->object->getSolutionValues($active_id, $pass);
254  }
255  else
256  {
257  $rank = array();
258  foreach ($this->object->answers as $answer)
259  {
260  if ($answer->getPoints() > 0)
261  {
262  if (!is_array($rank[$answer->getPoints()]))
263  {
264  $rank[$answer->getPoints()] = array();
265  }
266  array_push($rank[$answer->getPoints()], $answer->getAnswertext());
267  }
268  }
269  krsort($rank, SORT_NUMERIC);
270  foreach ($rank as $index => $bestsolutions)
271  {
272  array_push($solutions, array("value1" => join(",", $bestsolutions), "points" => $index));
273  }
274  }
275 
276  // generate the question output
277  include_once "./Services/UICore/classes/class.ilTemplate.php";
278  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
279  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
280  $available_answers =& $this->object->getAvailableAnswers();
281  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
282  {
283  if ((!$test_id) && (strcmp($solutions[$i]["value1"], "") == 0))
284  {
285  }
286  else
287  {
288  if (($active_id > 0) && (!$show_correct_solution))
289  {
290  if ($graphicalOutput)
291  {
292  // output of ok/not ok icons for user entered solutions
293  $index = $this->object->isAnswerCorrect($available_answers, $solutions[$i]["value1"]);
294  $correct = FALSE;
295  if ($index !== FALSE)
296  {
297  unset($available_answers[$index]);
298  $correct = TRUE;
299  }
300  if ($correct)
301  {
302  $template->setCurrentBlock("icon_ok");
303  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.png"));
304  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
305  $template->parseCurrentBlock();
306  }
307  else
308  {
309  $template->setCurrentBlock("icon_ok");
310  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.png"));
311  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
312  $template->parseCurrentBlock();
313  }
314  }
315  }
316  $template->setCurrentBlock("textsubset_row");
317  $template->setVariable("SOLUTION", $solutions[$i]["value1"]);
318  $template->setVariable("COUNTER", $i+1);
319  if ($result_output)
320  {
321  $points = $solutions[$i]["points"];
322  $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
323  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
324  }
325  $template->parseCurrentBlock();
326  }
327  }
328  $questiontext = $this->object->getQuestion();
329  if ($show_question_text==true)
330  {
331  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
332  }
333  $questionoutput = $template->get();
334  $feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
335  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
336  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
337 
338  $solutionoutput = $solutiontemplate->get();
339  if (!$show_question_only)
340  {
341  // get page object output
342  $solutionoutput = '<div class="ilc_question_Standard">'.$solutionoutput."</div>";
343  }
344  return $solutionoutput;
345  }
346 
347  function getPreview($show_question_only = FALSE)
348  {
349  // generate the question output
350  include_once "./Services/UICore/classes/class.ilTemplate.php";
351  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
352  $width = $this->object->getMaxTextboxWidth();
353  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
354  {
355  $template->setCurrentBlock("textsubset_row");
356  $template->setVariable("COUNTER", $i+1);
357  $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
358  $template->setVariable("TEXTFIELD_SIZE", $width);
359  $template->parseCurrentBlock();
360  }
361  $questiontext = $this->object->getQuestion();
362  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
363  $questionoutput = $template->get();
364  if (!$show_question_only)
365  {
366  // get page object output
367  $questionoutput = $this->getILIASPage($questionoutput);
368  }
369  return $questionoutput;
370  }
371 
372  function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
373  {
374  // get the solution of the user for the active pass or from the last pass if allowed
375  $user_solution = "";
376  if ($active_id)
377  {
378  $solutions = NULL;
379  include_once "./Modules/Test/classes/class.ilObjTest.php";
380  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
381  {
382  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
383  }
384  $solutions =& $this->object->getSolutionValues($active_id, $pass);
385  }
386 
387  // generate the question output
388  include_once "./Services/UICore/classes/class.ilTemplate.php";
389  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
390  $width = $this->object->getMaxTextboxWidth();
391  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
392  {
393  $template->setCurrentBlock("textsubset_row");
394  foreach ($solutions as $idx => $solution_value)
395  {
396  if ($idx == $i)
397  {
398  $template->setVariable("TEXTFIELD_VALUE", " value=\"" . ilUtil::prepareFormOutput($solution_value["value1"])."\"");
399  }
400  }
401  $template->setVariable("COUNTER", $i+1);
402  $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
403  $template->setVariable("TEXTFIELD_SIZE", $width);
404  $template->parseCurrentBlock();
405  }
406  $questiontext = $this->object->getQuestion();
407  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
408  $questionoutput = $template->get();
409  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
410  return $pageoutput;
411  }
412 
418  function saveFeedback()
419  {
420  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
421  $errors = $this->feedback(true);
422  $this->object->saveFeedbackGeneric(0, $_POST["feedback_incomplete"]);
423  $this->object->saveFeedbackGeneric(1, $_POST["feedback_complete"]);
424  $this->object->cleanupMediaObjectUsage();
426  }
427 
435  function setQuestionTabs()
436  {
437  global $rbacsystem, $ilTabs;
438 
439  $this->ctrl->setParameterByClass("ilpageobjectgui", "q_id", $_GET["q_id"]);
440  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
441  $q_type = $this->object->getQuestionType();
442 
443  if (strlen($q_type))
444  {
445  $classname = $q_type . "GUI";
446  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
447  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
448  }
449 
450  if ($_GET["q_id"])
451  {
452  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
453  {
454  // edit page
455  $ilTabs->addTarget("edit_page",
456  $this->ctrl->getLinkTargetByClass("ilPageObjectGUI", "edit"),
457  array("edit", "insert", "exec_pg"),
458  "", "", $force_active);
459  }
460 
461  // edit page
462  $ilTabs->addTarget("preview",
463  $this->ctrl->getLinkTargetByClass("ilPageObjectGUI", "preview"),
464  array("preview"),
465  "ilPageObjectGUI", "", $force_active);
466  }
467 
468  $force_active = false;
469  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
470  {
471  $url = "";
472  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
473  // edit question properties
474  $ilTabs->addTarget("edit_question",
475  $url,
476  array("editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "originalSyncForm"),
477  $classname, "", $force_active);
478  }
479 
480  if ($_GET["q_id"])
481  {
482  $ilTabs->addTarget("feedback",
483  $this->ctrl->getLinkTargetByClass($classname, "feedback"),
484  array("feedback", "saveFeedback"),
485  $classname, "");
486  }
487 
488  // add tab for question hint within common class assQuestionGUI
489  $this->addTab_QuestionHints($ilTabs);
490 
491  if ($_GET["q_id"])
492  {
493  $ilTabs->addTarget("solution_hint",
494  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
495  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
496  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
497  ),
498  $classname,
499  ""
500  );
501  }
502 
503  // Assessment of questions sub menu entry
504  if ($_GET["q_id"])
505  {
506  $ilTabs->addTarget("statistics",
507  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
508  array("assessment"),
509  $classname, "");
510  }
511 
512  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
513  {
514  $ref_id = $_GET["calling_test"];
515  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
516 
517  global $___test_express_mode;
518 
519  if (!$_GET['test_express_mode'] && !$___test_express_mode) {
520  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
521  }
522  else {
524  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
525  }
526  }
527  else
528  {
529  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
530  }
531  }
532 
533  function getSpecificFeedbackOutput($active_id, $pass)
534  {
535  $output = "";
536  return $this->object->prepareTextareaOutput($output, TRUE);
537  }
538 }