ILIAS  Release_4_1_x_branch Revision 61804
 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 
38 {
47  function __construct($id = -1)
48  {
50  include_once "./Modules/TestQuestionPool/classes/class.assTextQuestion.php";
51  $this->object = new assTextQuestion();
52  if ($id >= 0)
53  {
54  $this->object->loadFromDb($id);
55  }
56  }
57 
64  function writePostData($always = false)
65  {
66  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
67  if (!$hasErrors)
68  {
69  $this->object->setTitle($_POST["title"]);
70  $this->object->setAuthor($_POST["author"]);
71  $this->object->setComment($_POST["comment"]);
72  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
73  $questiontext = $_POST["question"];
74  $this->object->setQuestion($questiontext);
75  $this->object->setPoints($_POST["points"]);
76  $this->object->setMaxNumOfChars($_POST["maxchars"]);
77  $this->object->setKeywords($_POST["keywords"]);
78  $this->object->setTextRating($_POST["text_rating"]);
79  if ($this->getSelfAssessmentEditingMode())
80  {
81  $this->object->setNrOfTries($_POST['nr_of_tries']);
82  }
83  $this->object->setEstimatedWorkingTime(
84  $_POST["Estimated"]["hh"],
85  $_POST["Estimated"]["mm"],
86  $_POST["Estimated"]["ss"]
87  );
88  return 0;
89  }
90  else
91  {
92  return 1;
93  }
94  }
95 
101  public function editQuestion($checkonly = FALSE)
102  {
103  $save = ((strcmp($this->ctrl->getCmd(), "save") == 0) || (strcmp($this->ctrl->getCmd(), "saveEdit") == 0)) ? TRUE : FALSE;
104  $this->getQuestionTemplate();
105 
106  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
107  $form = new ilPropertyFormGUI();
108  $form->setFormAction($this->ctrl->getFormAction($this));
109  $form->setTitle($this->outQuestionType());
110  $form->setMultipart(TRUE);
111  $form->setTableWidth("100%");
112  $form->setId("asstextquestion");
113 
114  // title, author, description, question, working time (assessment mode)
115  $this->addBasicQuestionFormProperties($form);
116 
117  // maxchars
118  $maxchars = new ilNumberInputGUI($this->lng->txt("maxchars"), "maxchars");
119  $maxchars->setSize(5);
120  if ($this->object->getMaxNumOfChars() > 0) $maxchars->setValue($this->object->getMaxNumOfChars());
121  $maxchars->setInfo($this->lng->txt("description_maxchars"));
122  $form->addItem($maxchars);
123 
124  if (!$this->getSelfAssessmentEditingMode())
125  {
126  // points
127  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
128  $points->setValue($this->object->getPoints());
129  $points->setRequired(TRUE);
130  $points->setSize(3);
131  $points->setMinValue(0.0);
132  $points->setMinvalueShouldBeGreater(true);
133  $form->addItem($points);
134 
135  $header = new ilFormSectionHeaderGUI();
136  $header->setTitle($this->lng->txt("optional_keywords"));
137  $form->addItem($header);
138 
139  // keywords
140  $keywords = new ilTextAreaInputGUI($this->lng->txt("keywords"), "keywords");
141  $keywords->setValue(ilUtil::prepareFormOutput($this->object->getKeywords()));
142  $keywords->setRequired(FALSE);
143  $keywords->setInfo($this->lng->txt("keywords_hint"));
144  $keywords->setRows(10);
145  $keywords->setCols(40);
146  $keywords->setUseRte(FALSE);
147  $form->addItem($keywords);
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  "l1" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "1"),
154  "l2" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "2"),
155  "l3" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "3"),
156  "l4" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "4"),
157  "l5" => sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "5")
158  );
159  $textrating->setOptions($text_options);
160  $textrating->setValue($this->object->getTextRating());
161  $form->addItem($textrating);
162  }
163 
164  $this->addQuestionFormCommandButtons($form);
165  $errors = false;
166 
167  if ($save)
168  {
169  $form->setValuesByPost();
170  $errors = !$form->checkInput();
171  $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
172  if ($errors) $checkonly = false;
173  }
174 
175  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
176  return $errors;
177  }
178 
180  {
181  if ($this->object->getMaxNumOfChars() > 0)
182  {
183  $this->tpl->addBlockFile("CONTENT_BLOCK", "charcounter", "tpl.charcounter.html", "Modules/TestQuestionPool");
184  $this->tpl->setCurrentBlock("charcounter");
185  $this->tpl->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
186  $this->tpl->parseCurrentBlock();
187  }
188  }
189 
190  function outQuestionForTest($formaction, $active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
191  {
192  $test_output = $this->getTestOutput($active_id, $pass, $is_postponed, $use_post_solutions);
193  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
194  $this->tpl->setVariable("FORMACTION", $formaction);
195  include_once "./Services/RTE/classes/class.ilRTE.php";
196  $rtestring = ilRTE::_getRTEClassname();
197  include_once "./Services/RTE/classes/class.$rtestring.php";
198  $rte = new $rtestring();
199  include_once "./classes/class.ilObject.php";
200  $obj_id = ilObject::_lookupObjectId($_GET["ref_id"]);
201  $obj_type = ilObject::_lookupType($_GET["ref_id"], TRUE);
202  $rte->addUserTextEditor("textinput");
203  $this->outAdditionalOutput();
204  }
205 
220  $active_id,
221  $pass = NULL,
222  $graphicalOutput = FALSE,
223  $result_output = FALSE,
224  $show_question_only = TRUE,
225  $show_feedback = FALSE,
226  $show_correct_solution = FALSE,
227  $show_manual_scoring = FALSE
228  )
229  {
230  // get the solution of the user for the active pass or from the last pass if allowed
231  $user_solution = "";
232  if (($active_id > 0) && (!$show_correct_solution))
233  {
234  $solutions =& $this->object->getSolutionValues($active_id, $pass);
235  foreach ($solutions as $idx => $solution_value)
236  {
237  $user_solution = $solution_value["value1"];
238  }
239  }
240  else
241  {
242  $keywords = $this->object->getKeywordList();
243  if (count($keywords))
244  {
245  $user_solution = $this->lng->txt("solution_may_contain_keywords") . ": " . join(",", $keywords);
246  }
247  }
248 
249  // generate the question output
250  include_once "./classes/class.ilTemplate.php";
251  $template = new ilTemplate("tpl.il_as_qpl_text_question_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
252  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
253  $template->setVariable("ESSAY", $this->object->prepareTextareaOutput($user_solution, TRUE));
254  $questiontext = $this->object->getQuestion();
255  $max_no_of_chars = $this->object->getMaxNumOfChars();
256  $act_no_of_chars = strlen(strip_tags($user_solution));
257  $template->setVariable("CHARACTER_INFO", '<b>' . $max_no_of_chars . '</b>' . $this->lng->txt('answer_characters') . ' <b>' . $act_no_of_chars . '</b>');
258  if (($active_id > 0) && (!$show_correct_solution))
259  {
260  if ($graphicalOutput)
261  {
262  // output of ok/not ok icons for user entered solutions
263  $reached_points = $this->object->getReachedPoints($active_id, $pass);
264  if ($reached_points == $this->object->getMaximumPoints())
265  {
266  $template->setCurrentBlock("icon_ok");
267  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.gif"));
268  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
269  $template->parseCurrentBlock();
270  }
271  else
272  {
273  $template->setCurrentBlock("icon_ok");
274  if ($reached_points > 0)
275  {
276  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.gif"));
277  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
278  }
279  else
280  {
281  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.gif"));
282  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
283  }
284  $template->parseCurrentBlock();
285  }
286  }
287  }
288  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
289  $questionoutput = $template->get();
290  $feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
291  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $feedback);
292  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
293 
294  $solutionoutput = $solutiontemplate->get();
295  if (!$show_question_only)
296  {
297  // get page object output
298  $solutionoutput = $this->getILIASPage($solutionoutput);
299  }
300  return $solutionoutput;
301  }
302 
303  function getPreview($show_question_only = FALSE)
304  {
305  // generate the question output
306  include_once "./classes/class.ilTemplate.php";
307  $template = new ilTemplate("tpl.il_as_qpl_text_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
308  if ($this->object->getMaxNumOfChars())
309  {
310  $template->setCurrentBlock("maximum_char_hint");
311  $template->setVariable("MAXIMUM_CHAR_HINT", sprintf($this->lng->txt("text_maximum_chars_allowed"), $this->object->getMaxNumOfChars()));
312  $template->parseCurrentBlock();
313  #mbecker: No such block. $template->setCurrentBlock("has_maxchars");
314  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
315  $template->parseCurrentBlock();
316  $template->setCurrentBlock("maxchars_counter");
317  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
318  $template->setVariable("TEXTBOXSIZE", strlen($this->object->getMaxNumOfChars()));
319  $template->setVariable("CHARACTERS", $this->lng->txt("characters"));
320  $template->parseCurrentBlock();
321  }
322  $questiontext = $this->object->getQuestion();
323  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
324  $questionoutput = $template->get();
325  if (!$show_question_only)
326  {
327  // get page object output
328  $questionoutput = $this->getILIASPage($questionoutput);
329  }
330  return $questionoutput;
331  }
332 
333  function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
334  {
335  // get the solution of the user for the active pass or from the last pass if allowed
336  $user_solution = "";
337  if ($active_id)
338  {
339  $solutions = NULL;
340  include_once "./Modules/Test/classes/class.ilObjTest.php";
341  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
342  {
343  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
344  }
345  $solutions =& $this->object->getSolutionValues($active_id, $pass);
346  foreach ($solutions as $idx => $solution_value)
347  {
348  $user_solution = $solution_value["value1"];
349  }
350  }
351 
352  // generate the question output
353  include_once "./classes/class.ilTemplate.php";
354  $template = new ilTemplate("tpl.il_as_qpl_text_question_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
355  if ($this->object->getMaxNumOfChars())
356  {
357  $template->setCurrentBlock("maximum_char_hint");
358  $template->setVariable("MAXIMUM_CHAR_HINT", sprintf($this->lng->txt("text_maximum_chars_allowed"), $this->object->getMaxNumOfChars()));
359  $template->parseCurrentBlock();
360  #mbecker: No such block. $template->setCurrentBlock("has_maxchars");
361  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
362  $template->parseCurrentBlock();
363  $template->setCurrentBlock("maxchars_counter");
364  $template->setVariable("MAXCHARS", $this->object->getMaxNumOfChars());
365  $template->setVariable("TEXTBOXSIZE", strlen($this->object->getMaxNumOfChars()));
366  $template->setVariable("CHARACTERS", $this->lng->txt("characters"));
367  $template->parseCurrentBlock();
368  }
369  $template->setVariable("ESSAY", ilUtil::prepareFormOutput($user_solution));
370  $questiontext = $this->object->getQuestion();
371  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
372  $questionoutput = $template->get();
373  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
374  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
376  return $pageoutput;
377  }
378 
380  {
381  $_SESSION["subquestion_index"] = 0;
382  if ($_POST["cmd"]["addSuggestedSolution"])
383  {
384  if ($this->writePostData())
385  {
387  $this->editQuestion();
388  return;
389  }
390  if (!$this->checkInput())
391  {
392  ilUtil::sendInfo($this->lng->txt("fill_out_all_required_fields_add_answer"));
393  $this->editQuestion();
394  return;
395  }
396  }
397  $this->object->saveToDb();
398  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
399  $this->tpl->setVariable("HEADER", $this->object->getTitle());
400  $this->getQuestionTemplate();
402  }
403 
409  function saveFeedback()
410  {
411  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
412  $errors = $this->feedback(true);
413  $this->object->saveFeedbackGeneric(0, $_POST["feedback_incomplete"]);
414  $this->object->saveFeedbackGeneric(1, $_POST["feedback_complete"]);
415  $this->object->cleanupMediaObjectUsage();
417  }
418 
424  function setQuestionTabs()
425  {
426  global $rbacsystem, $ilTabs;
427 
428  $this->ctrl->setParameterByClass("ilpageobjectgui", "q_id", $_GET["q_id"]);
429  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
430  $q_type = $this->object->getQuestionType();
431 
432  if (strlen($q_type))
433  {
434  $classname = $q_type . "GUI";
435  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
436  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
437  }
438 
439  if ($_GET["q_id"])
440  {
441  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
442  {
443  // edit page
444  $ilTabs->addTarget("edit_content",
445  $this->ctrl->getLinkTargetByClass("ilPageObjectGUI", "edit"),
446  array("edit", "insert", "exec_pg"),
447  "", "", $force_active);
448  }
449 
450  // edit page
451  $ilTabs->addTarget("preview",
452  $this->ctrl->getLinkTargetByClass("ilPageObjectGUI", "preview"),
453  array("preview"),
454  "ilPageObjectGUI", "", $force_active);
455  }
456 
457  $force_active = false;
458  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
459  {
460  $url = "";
461  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
462  // edit question properties
463  $ilTabs->addTarget("edit_properties",
464  $url,
465  array("editQuestion", "save", "saveEdit", "originalSyncForm"),
466  $classname, "", $force_active);
467  }
468 
469  if ($_GET["q_id"])
470  {
471  $ilTabs->addTarget("feedback",
472  $this->ctrl->getLinkTargetByClass($classname, "feedback"),
473  array("feedback", "saveFeedback"),
474  $classname, "");
475  }
476 
477  if ($_GET["q_id"])
478  {
479  $ilTabs->addTarget("solution_hint",
480  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
481  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
482  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
483  ),
484  $classname,
485  ""
486  );
487  }
488 
489  // Assessment of questions sub menu entry
490  if ($_GET["q_id"])
491  {
492  $ilTabs->addTarget("statistics",
493  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
494  array("assessment"),
495  $classname, "");
496  }
497 
498  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
499  {
500  $ref_id = $_GET["calling_test"];
501  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
502  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
503  }
504  else
505  {
506  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
507  }
508  }
509 }
510 ?>