ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.assTextSubsetGUI.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 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
8 
25 {
33  public function __construct($id = -1)
34  {
35  parent::__construct();
36  require_once './Modules/TestQuestionPool/classes/class.assTextSubset.php';
37  $this->object = new assTextSubset();
38  if ($id >= 0) {
39  $this->object->loadFromDb($id);
40  }
41  }
42 
46  protected function writePostData($always = false)
47  {
48  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
49  if (!$hasErrors) {
50  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
54  $this->saveTaxonomyAssignments();
55  return 0;
56  }
57  return 1;
58  }
59 
63  public function editQuestion($checkonly = false)
64  {
65  $save = $this->isSaveCommand();
66  $this->getQuestionTemplate();
67 
68  require_once './Services/Form/classes/class.ilPropertyFormGUI.php';
69  $form = new ilPropertyFormGUI();
70  $this->editForm = $form;
71 
72  $form->setFormAction($this->ctrl->getFormAction($this));
73  $form->setTitle($this->outQuestionType());
74  $form->setMultipart(false);
75  $form->setTableWidth("100%");
76  $form->setId("asstextsubset");
77 
83 
84  $errors = false;
85  if ($save) {
86  $form->setValuesByPost();
87  $points = $form->getItemByPostVar('points');
88  $points->setValue($this->object->getMaximumPoints());
89  $errors = !$form->checkInput();
90  $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
91  if ($errors) {
92  $checkonly = false;
93  }
94  }
95 
96  if (!$checkonly) {
97  $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
98  }
99  return $errors;
100  }
101 
105  public function addanswers()
106  {
107  $this->writePostData(true);
108  $position = key($_POST['cmd']['addanswers']);
109  $this->object->addAnswer("", 0, $position+1);
110  $this->editQuestion();
111  }
112 
116  public function removeanswers()
117  {
118  $this->writePostData(true);
119  $position = key($_POST['cmd']['removeanswers']);
120  $this->object->deleteAnswer($position);
121  $this->editQuestion();
122  }
123 
137  public function getSolutionOutput(
138  $active_id,
139  $pass = null,
140  $graphicalOutput = false,
141  $result_output = false,
142  $show_question_only = true,
143  $show_feedback = false,
144  $show_correct_solution = false,
145  $show_manual_scoring = false,
146  $show_question_text = true
147  ) {
148  // get the solution of the user for the active pass or from the last pass if allowed
149  $solutions = array();
150  if (($active_id > 0) && (!$show_correct_solution)) {
151  $solutions =&$this->object->getSolutionValues($active_id, $pass);
152  } else {
153  $rank = array();
154  foreach ($this->object->answers as $answer) {
155  if ($answer->getPoints() > 0) {
156  if (!is_array($rank[$answer->getPoints()])) {
157  $rank[$answer->getPoints()] = array();
158  }
159  array_push($rank[$answer->getPoints()], $answer->getAnswertext());
160  }
161  }
162  krsort($rank, SORT_NUMERIC);
163  foreach ($rank as $index => $bestsolutions) {
164  array_push($solutions, array("value1" => join(",", $bestsolutions), "points" => $index));
165  }
166  }
167 
168  // generate the question output
169  include_once "./Services/UICore/classes/class.ilTemplate.php";
170  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output_solution.html", true, true, "Modules/TestQuestionPool");
171  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
172  $available_answers =&$this->object->getAvailableAnswers();
173  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++) {
174  if ((!$test_id) && (strcmp($solutions[$i]["value1"], "") == 0)) {
175  } else {
176  if (($active_id > 0) && (!$show_correct_solution)) {
177  if ($graphicalOutput) {
178  // output of ok/not ok icons for user entered solutions
179  $index = $this->object->isAnswerCorrect($available_answers, $solutions[$i]["value1"]);
180  $correct = false;
181  if ($index !== false) {
182  unset($available_answers[$index]);
183  $correct = true;
184  }
185  if ($correct) {
186  $template->setCurrentBlock("icon_ok");
187  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
188  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
189  $template->parseCurrentBlock();
190  } else {
191  $template->setCurrentBlock("icon_ok");
192  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
193  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
194  $template->parseCurrentBlock();
195  }
196  }
197  }
198  $template->setCurrentBlock("textsubset_row");
199  $template->setVariable("SOLUTION", $solutions[$i]["value1"]);
200  $template->setVariable("COUNTER", $i+1);
201  if ($result_output) {
202  $points = $solutions[$i]["points"];
203  $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
204  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
205  }
206  $template->parseCurrentBlock();
207  }
208  }
209  $questiontext = $this->object->getQuestion();
210  if ($show_question_text==true) {
211  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
212  }
213  $questionoutput = $template->get();
214  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
215  if (strlen($feedback)) {
216  $cssClass = (
217  $this->hasCorrectSolution($active_id, $pass) ?
219  );
220 
221  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
222  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
223  }
224  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
225 
226  $solutionoutput = $solutiontemplate->get();
227  if (!$show_question_only) {
228  // get page object output
229  $solutionoutput = $this->getILIASPage($solutionoutput);
230  }
231  return $solutionoutput;
232  }
233 
234  public function getPreview($show_question_only = false, $showInlineFeedback = false)
235  {
236  $solutions = is_object($this->getPreviewSession()) ? (array) $this->getPreviewSession()->getParticipantsSolution() : array();
237  // generate the question output
238  include_once "./Services/UICore/classes/class.ilTemplate.php";
239  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", true, true, "Modules/TestQuestionPool");
240  $width = $this->object->getMaxTextboxWidth();
241  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++) {
242  $template->setCurrentBlock("textsubset_row");
243  foreach ($solutions as $idx => $solution_value) {
244  if ($idx == $i) {
245  $template->setVariable("TEXTFIELD_VALUE", " value=\"" . $solution_value . "\"");
246  }
247  }
248  $template->setVariable("COUNTER", $i+1);
249  $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
250  $template->setVariable("TEXTFIELD_SIZE", $width);
251  $template->parseCurrentBlock();
252  }
253  $questiontext = $this->object->getQuestion();
254  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
255  $questionoutput = $template->get();
256  if (!$show_question_only) {
257  // get page object output
258  $questionoutput = $this->getILIASPage($questionoutput);
259  }
260  return $questionoutput;
261  }
262 
263  public function getTestOutput($active_id, $pass = null, $is_postponed = false, $use_post_solutions = false, $inlineFeedback = false)
264  {
265  // get the solution of the user for the active pass or from the last pass if allowed
266  $user_solution = "";
267  if ($active_id) {
268  $solutions = null;
269  // hey: prevPassSolutions - obsolete due to central check
270  #include_once "./Modules/Test/classes/class.ilObjTest.php";
271  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
272  #{
273  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
274  #}
275  // hey.
276  $solutions = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
277  }
278 
279  // generate the question output
280  include_once "./Services/UICore/classes/class.ilTemplate.php";
281  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", true, true, "Modules/TestQuestionPool");
282  $width = $this->object->getMaxTextboxWidth();
283  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++) {
284  $template->setCurrentBlock("textsubset_row");
285  foreach ($solutions as $idx => $solution_value) {
286  if ($idx == $i) {
287  $template->setVariable("TEXTFIELD_VALUE", " value=\"" . ilUtil::prepareFormOutput($solution_value["value1"]) . "\"");
288  }
289  }
290  $template->setVariable("COUNTER", $i+1);
291  $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
292  $template->setVariable("TEXTFIELD_SIZE", $width);
293  $template->parseCurrentBlock();
294  }
295  $questiontext = $this->object->getQuestion();
296  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
297  $questionoutput = $template->get();
298  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
299  return $pageoutput;
300  }
301 
309  public function setQuestionTabs()
310  {
311  global $rbacsystem, $ilTabs;
312 
313  $ilTabs->clearTargets();
314 
315  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
316  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
317  $q_type = $this->object->getQuestionType();
318 
319  if (strlen($q_type)) {
320  $classname = $q_type . "GUI";
321  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
322  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
323  }
324 
325  if ($_GET["q_id"]) {
326  if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
327  // edit page
328  $ilTabs->addTarget(
329  "edit_page",
330  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
331  array("edit", "insert", "exec_pg"),
332  "",
333  "",
334  $force_active
335  );
336  }
337 
338  $this->addTab_QuestionPreview($ilTabs);
339  }
340 
341  $force_active = false;
342  if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
343  $url = "";
344  if ($classname) {
345  $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
346  }
347  // edit question properties
348  $ilTabs->addTarget(
349  "edit_question",
350  $url,
351  array("editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "originalSyncForm"),
352  $classname,
353  "",
354  $force_active
355  );
356  }
357 
358  // add tab for question feedback within common class assQuestionGUI
359  $this->addTab_QuestionFeedback($ilTabs);
360 
361  // add tab for question hint within common class assQuestionGUI
362  $this->addTab_QuestionHints($ilTabs);
363 
364  // add tab for question's suggested solution within common class assQuestionGUI
365  $this->addTab_SuggestedSolution($ilTabs, $classname);
366 
367  // Assessment of questions sub menu entry
368  if ($_GET["q_id"]) {
369  $ilTabs->addTarget(
370  "statistics",
371  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
372  array("assessment"),
373  $classname,
374  ""
375  );
376  }
377 
378  $this->addBackTab($ilTabs);
379  }
380 
381  public function getSpecificFeedbackOutput($active_id, $pass)
382  {
383  $output = "";
384  return $this->object->prepareTextareaOutput($output, true);
385  }
386 
388  {
389  $this->object->setCorrectAnswers($_POST["correctanswers"]);
390  $this->object->setTextRating($_POST["text_rating"]);
391  }
392 
394  {
395  // Delete all existing answers and create new answers from the form data
396  $this->object->flushAnswers();
397  foreach ($_POST['answers']['answer'] as $index => $answer) {
398  $answertext = $answer;
399  $this->object->addAnswer($answertext, $_POST['answers']['points'][$index], $index);
400  }
401  }
402 
404  {
405  // number of requested answers
406  $correctanswers = new ilNumberInputGUI($this->lng->txt("nr_of_correct_answers"), "correctanswers");
407  $correctanswers->setMinValue(1);
408  $correctanswers->setDecimals(0);
409  $correctanswers->setSize(3);
410  $correctanswers->setValue($this->object->getCorrectAnswers());
411  $correctanswers->setRequired(true);
412  $form->addItem($correctanswers);
413 
414  // maximum available points
415  $points = new ilNumberInputGUI($this->lng->txt("maximum_points"), "points");
416  $points->setMinValue(0.0);
417  $points->setMinvalueShouldBeGreater(true);
418  $points->setSize(6);
419  $points->setDisabled(true);
420  $points->allowDecimals(true);
421  $points->setValue($this->object->getMaximumPoints());
422  $points->setRequired(false);
423  $form->addItem($points);
424 
425  // text rating
426  $textrating = new ilSelectInputGUI($this->lng->txt("text_rating"), "text_rating");
427  $text_options = array(
428  "ci" => $this->lng->txt("cloze_textgap_case_insensitive"),
429  "cs" => $this->lng->txt("cloze_textgap_case_sensitive")
430  );
431  if (!$this->object->getSelfAssessmentEditingMode()) {
432  $text_options["l1"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "1");
433  $text_options["l2"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "2");
434  $text_options["l3"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "3");
435  $text_options["l4"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "4");
436  $text_options["l5"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "5");
437  }
438  $textrating->setOptions($text_options);
439  $textrating->setValue($this->object->getTextRating());
440  $form->addItem($textrating);
441  return $form;
442  }
443 
445  {
446  // Choices
447  include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
448  $choices = new ilAnswerWizardInputGUI($this->lng->txt("answers"), "answers");
449  $choices->setRequired(true);
450  $choices->setQuestionObject($this->object);
451  $choices->setSingleline(true);
452  $choices->setAllowMove(false);
453  $choices->setMinValue(0.0);
454  if ($this->object->getAnswerCount() == 0) {
455  $this->object->addAnswer("", 0, 0);
456  }
457  $choices->setValues($this->object->getAnswers());
458  $form->addItem($choices);
459  return $form;
460  }
461 
462 
473  {
474  return array();
475  }
476 
487  {
488  return array();
489  }
490 
499  public function getAggregatedAnswersView($relevant_answers)
500  {
501  return $this->renderAggregateView(
502  $this->aggregateAnswers($relevant_answers)
503  )->get();
504  }
505 
506  public function aggregateAnswers($relevant_answers_chosen)
507  {
508  $aggregate = array();
509 
510  foreach ($relevant_answers_chosen as $relevant_answer) {
511  if (array_key_exists($relevant_answer['value1'], $aggregate)) {
512  $aggregate[$relevant_answer['value1']]++;
513  } else {
514  $aggregate[$relevant_answer['value1']] = 1;
515  }
516  }
517  return $aggregate;
518  }
519 
525  public function renderAggregateView($aggregate)
526  {
527  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
528 
529  foreach ($aggregate as $key => $value) {
530  $tpl->setCurrentBlock('aggregaterow');
531  $tpl->setVariable('OPTION', $key);
532  $tpl->setVariable('COUNT', $value);
533  $tpl->parseCurrentBlock();
534  }
535  return $tpl;
536  }
537 }
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
getPreview($show_question_only=false, $showInlineFeedback=false)
This class represents a selection list property in a property form.
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
$template
This class represents a property form user interface.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
$_GET["client_id"]
getSpecificFeedbackOutput($active_id, $pass)
if(!array_key_exists('StateId', $_REQUEST)) $id
Class for TextSubset questions.
addItem($a_item)
Add Item (Property, SectionHeader).
$index
Definition: metadata.php:60
getQuestionTemplate()
get question template
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
populateTaxonomyFormSection(ilPropertyFormGUI $form)
removeanswers()
Remove an answer.
This class represents a single choice wizard property in a property form.
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
setMinValue($a_minvalue, $a_display_always=false)
Set Minimum Value.
if(isset($_POST['submit'])) $form
getILIASPage($html="")
Returns the ILIAS Page around a question.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
This class represents a number property in a property form.
special template class to simplify handling of ITX/PEAR
writePostData($always=false)
{}
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
setOptions($a_options)
Set Options.
Basic GUI class for assessment questions.
Create styles array
The data for the language used.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
getTestOutput($active_id, $pass=null, $is_postponed=false, $use_post_solutions=false, $inlineFeedback=false)
$errors
Definition: index.php:6
Create new PHPExcel object
obj_idprivate
Multiple choice question GUI representation.
addBackTab(ilTabsGUI $ilTabs)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
$i
Definition: disco.tpl.php:19
Interface ilGuiAnswerScoringAdjustable.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
$url
Interface ilGuiQuestionScoringAdjustable.
__construct($id=-1)
assTextSubsetGUI constructor
setQuestionTabs()
Sets the ILIAS tabs for this question type.
aggregateAnswers($relevant_answers_chosen)
$key
Definition: croninfo.php:18
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
$_POST["username"]
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
setRequired($a_required)
Set Required.
addanswers()
Add a new answer.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.