ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f87
class.assErrorTextGUI.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 
8 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
9 
25 {
34  public function __construct($id = -1)
35  {
36  parent::__construct();
37  include_once "./Modules/TestQuestionPool/classes/class.assErrorText.php";
38  $this->object = new assErrorText();
39  $this->setErrorMessage($this->lng->txt("msg_form_save_error"));
40  if ($id >= 0)
41  {
42  $this->object->loadFromDb($id);
43  }
44  }
45 
54  function writePostData($always = false)
55  {
56  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
57  if (!$hasErrors)
58  {
59  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
63  $this->saveTaxonomyAssignments();
64  return 0;
65  }
66  return 1;
67  }
68 
70  {
71  if (is_array( $_POST['errordata']['key'] ))
72  {
73  $this->object->flushErrorData();
74  foreach ($_POST['errordata']['key'] as $idx => $val)
75  {
76  $this->object->addErrorData( $val,
77  $_POST['errordata']['value'][$idx],
78  $_POST['errordata']['points'][$idx]
79  );
80  }
81  }
82  }
83 
85  {
86  $questiontext = $_POST["question"];
87  $this->object->setQuestion( $questiontext );
88  $this->object->setErrorText( $_POST["errortext"] );
89  $points_wrong = str_replace( ",", ".", $_POST["points_wrong"] );
90  if (strlen( $points_wrong ) == 0)
91  $points_wrong = -1.0;
92  $this->object->setPointsWrong( $points_wrong );
93 
94  if (!$this->object->getSelfAssessmentEditingMode())
95  {
96  $this->object->setTextSize( $_POST["textsize"] );
97  }
98  }
99 
107  public function editQuestion($checkonly = FALSE)
108  {
109  $save = $this->isSaveCommand();
110  $this->getQuestionTemplate();
111 
112  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
113  $form = new ilPropertyFormGUI();
114  $form->setFormAction($this->ctrl->getFormAction($this));
115  $form->setTitle($this->outQuestionType());
116  $form->setMultipart(FALSE);
117  $form->setTableWidth("100%");
118  $form->setId("orderinghorizontal");
119 
120  $this->addBasicQuestionFormProperties( $form );
121 
122  $this->populateQuestionSpecificFormPart( $form );
123 
124  if (count($this->object->getErrorData()) || $checkonly)
125  {
126  $this->populateAnswerSpecificFormPart( $form );
127  }
128 
129  $this->populateTaxonomyFormSection($form);
130 
131  $form->addCommandButton("analyze", $this->lng->txt('analyze_errortext'));
132  $this->addQuestionFormCommandButtons($form);
133 
134  $errors = false;
135 
136  if ($save)
137  {
138  $form->setValuesByPost();
139  $errors = !$form->checkInput();
140  $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
141  if ($errors) $checkonly = false;
142  }
143 
144  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
145  return $errors;
146  }
147 
153  {
154  $header = new ilFormSectionHeaderGUI();
155  $header->setTitle( $this->lng->txt( "errors_section" ) );
156  $form->addItem( $header );
157 
158  include_once "./Modules/TestQuestionPool/classes/class.ilErrorTextWizardInputGUI.php";
159  $errordata = new ilErrorTextWizardInputGUI($this->lng->txt( "errors" ), "errordata");
160  $errordata->setKeyName( $this->lng->txt( 'text_wrong' ) );
161  $errordata->setValueName( $this->lng->txt( 'text_correct' ) );
162  $errordata->setValues( $this->object->getErrorData() );
163  $form->addItem( $errordata );
164 
165  // points for wrong selection
166  $points_wrong = new ilNumberInputGUI($this->lng->txt( "points_wrong" ), "points_wrong");
167  $points_wrong->allowDecimals(true);
168  $points_wrong->setValue( $this->object->getPointsWrong() );
169  $points_wrong->setInfo( $this->lng->txt( "points_wrong_info" ) );
170  $points_wrong->setSize( 6 );
171  $points_wrong->setRequired( true );
172  $form->addItem( $points_wrong );
173  return $form;
174  }
175 
181  {
182  // errortext
183  $errortext = new ilTextAreaInputGUI($this->lng->txt( "errortext" ), "errortext");
184  $errortext->setValue( $this->object->getErrorText() );
185  $errortext->setRequired( TRUE );
186  $errortext->setInfo( $this->lng->txt( "errortext_info" ) );
187  $errortext->setRows( 10 );
188  $errortext->setCols( 80 );
189  $form->addItem( $errortext );
190 
191  if (!$this->object->getSelfAssessmentEditingMode())
192  {
193  // textsize
194  $textsize = new ilNumberInputGUI($this->lng->txt( "textsize" ), "textsize");
195  $textsize->setValue( strlen( $this->object->getTextSize() ) ? $this->object->getTextSize() : 100.0 );
196  $textsize->setInfo( $this->lng->txt( "textsize_errortext_info" ) );
197  $textsize->setSize( 6 );
198  $textsize->setSuffix( "%" );
199  $textsize->setMinValue( 10 );
200  $textsize->setRequired( true );
201  $form->addItem( $textsize );
202  }
203  }
204 
208  public function analyze()
209  {
210  $this->writePostData(true);
211  $this->object->setErrorData($this->object->getErrorsFromText($_POST['errortext']));
212  $this->editQuestion();
213  }
214 
234  $active_id, $pass = NULL,
235  $graphicalOutput = FALSE,
236  $result_output = FALSE,
237  $show_question_only = TRUE,
238  $show_feedback = FALSE,
239  $show_correct_solution = FALSE,
240  $show_manual_scoring = FALSE,
241  $show_question_text = TRUE
242  )
243  {
244  // get the solution of the user for the active pass or from the last pass if allowed
245  $template = new ilTemplate("tpl.il_as_qpl_errortext_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
246 
247  $selections = array();
248  if (($active_id > 0) && (!$show_correct_solution)) {
249 
250  /* Retrieve tst_solutions entries. */
251  $reached_points = $this->object->getReachedPoints($active_id, $pass);
252  $solutions =& $this->object->getSolutionValues($active_id, $pass);
253  if (is_array($solutions)) {
254  foreach ($solutions as $solution) {
255  array_push($selections, (int) $solution['value1']);
256  }
257  $errortext_value = join(",", $selections);
258  }
259  }
260  else {
261  $selections = $this->object->getBestSelection();
262  $reached_points = $this->object->getPoints();
263  }
264 
265  if ($result_output) {
266  $resulttext = ($reached_points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
267  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $reached_points));
268  }
269 
270  if ($this->object->getTextSize() >= 10)
271  $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
272 
273  if ($show_question_text==true)
274  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), TRUE));
275 
276  $errortext = $this->object->createErrorTextOutput($selections, $graphicalOutput, $show_correct_solution);
277 
278  $template->setVariable("ERRORTEXT", $errortext);
279  $questionoutput = $template->get();
280 
281  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
282 
283  $feedback = '';
284  if($show_feedback)
285  {
286  $fb = $this->getGenericFeedbackOutput($active_id, $pass);
287  $feedback .= strlen($fb) ? $fb : '';
288 
289  $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
290  $feedback .= strlen($fb) ? $fb : '';
291  }
292  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $feedback);
293 
294  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
295 
296  $solutionoutput = $solutiontemplate->get();
297  if (!$show_question_only)
298  {
299  // get page object output
300  $solutionoutput = $this->getILIASPage($solutionoutput);
301  }
302  return $solutionoutput;
303  }
304 
305  function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
306  {
307  $selections = is_object($this->getPreviewSession()) ? (array)$this->getPreviewSession()->getParticipantsSolution() : array();
308 
309  $template = new ilTemplate("tpl.il_as_qpl_errortext_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
310  if ($this->object->getTextSize() >= 10) $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
311  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), TRUE));
312  $errortext = $this->object->createErrorTextOutput($selections);
313  $template->setVariable("ERRORTEXT", $errortext);
314  $template->setVariable("ERRORTEXT_ID", "qst_" . $this->object->getId());
315  $questionoutput = $template->get();
316  if (!$show_question_only)
317  {
318  // get page object output
319  $questionoutput = $this->getILIASPage($questionoutput);
320  }
321  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/errortext.js");
322  return $questionoutput;
323  }
324 
325  function getTestOutput(
326  $active_id,
327  $pass = NULL,
328  $is_postponed = FALSE,
329  $use_post_solutions = FALSE,
330  $show_feedback = FALSE
331  )
332  {
333  // generate the question output
334  $template = new ilTemplate("tpl.il_as_qpl_errortext_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
335  if ($active_id)
336  {
337  $solutions = NULL;
338  include_once "./Modules/Test/classes/class.ilObjTest.php";
339  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
340  {
341  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
342  }
343  $solutions =& $this->object->getSolutionValues($active_id, $pass);
344  }
345  $errortext_value = "";
346  $selections = array();
347  if (is_array($solutions))
348  {
349  foreach ($solutions as $solution)
350  {
351  array_push($selections, $solution['value1']);
352  }
353  $errortext_value = join(",", $selections);
354  }
355  if ($this->object->getTextSize() >= 10) $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
356  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), TRUE));
357  $errortext = $this->object->createErrorTextOutput($selections);
358  $this->ctrl->setParameterByClass($this->getTargetGuiClass(), 'errorvalue', '');
359  $template->setVariable("ERRORTEXT", $errortext);
360  $template->setVariable("ERRORTEXT_ID", "qst_" . $this->object->getId());
361  $template->setVariable("ERRORTEXT_VALUE", $errortext_value);
362 
363  $questionoutput = $template->get();
364  if (!$show_question_only)
365  {
366  // get page object output
367  $questionoutput = $this->getILIASPage($questionoutput);
368  }
369  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/errortext.js");
370  $questionoutput = $template->get();
371  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
372  return $pageoutput;
373  }
374 
382  function setQuestionTabs()
383  {
384  global $rbacsystem, $ilTabs;
385 
386  $ilTabs->clearTargets();
387 
388  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
389  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
390  $q_type = $this->object->getQuestionType();
391 
392  if (strlen($q_type))
393  {
394  $classname = $q_type . "GUI";
395  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
396  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
397  }
398 
399  if ($_GET["q_id"])
400  {
401  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
402  {
403  // edit page
404  $ilTabs->addTarget("edit_page",
405  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
406  array("edit", "insert", "exec_pg"),
407  "", "", $force_active);
408  }
409 
410  $this->addTab_QuestionPreview($ilTabs);
411  }
412 
413  $force_active = false;
414  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
415  {
416  $url = "";
417  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
418  // edit question properties
419  $ilTabs->addTarget("edit_question",
420  $url,
421  array("editQuestion", "save", "saveEdit", "analyze", "originalSyncForm"),
422  $classname, "", $force_active);
423  }
424 
425  // add tab for question feedback within common class assQuestionGUI
426  $this->addTab_QuestionFeedback($ilTabs);
427 
428  // add tab for question hint within common class assQuestionGUI
429  $this->addTab_QuestionHints($ilTabs);
430 
431  // add tab for question's suggested solution within common class assQuestionGUI
432  $this->addTab_SuggestedSolution($ilTabs, $classname);
433 
434  // Assessment of questions sub menu entry
435  if ($_GET["q_id"])
436  {
437  $ilTabs->addTarget("statistics",
438  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
439  array("assessment"),
440  $classname, "");
441  }
442 
443  $this->addBackTab($ilTabs);
444  }
445 
446  function getSpecificFeedbackOutput($active_id, $pass)
447  {
448  $selection = $this->object->getBestSelection(false);
449 
450  if( !$this->object->feedbackOBJ->specificAnswerFeedbackExists(array_keys($selection)) )
451  {
452  return '';
453  }
454 
455  $feedback = '<table class="test_specific_feedback"><tbody>';
456 
457  $elements = array();
458  foreach(preg_split("/[\n\r]+/", $this->object->errortext) as $line)
459  {
460  $elements = array_merge( $elements, preg_split("/\s+/", $line));
461  }
462 
463  $matchedIndexes = array();
464 
465  $i = 0;
466  foreach ($selection as $index => $answer)
467  {
468  $element = array();
469  foreach($answer as $answerPartIndex)
470  {
471  $element[] = $elements[$answerPartIndex];
472  }
473 
474  $element = implode(' ', $element);
475  $element = str_replace(array('((', '))', '#'), array('', '', ''), $element);
476 
477  $ordinal = $index + 1;
478 
479  $feedback .= '<tr>';
480 
481  $feedback .= '<td class="text-nowrap">' . $ordinal . '. ' . $element . ':</td>';
482 
483  foreach ($this->object->getErrorData() as $idx => $ans)
484  {
485  if( isset($matchedIndexes[$idx]) )
486  {
487  continue;
488  }
489 
490  if ( preg_match('/'.preg_quote($ans->text_wrong, '/').'/', $element) )
491  {
492  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
493  $this->object->getId(), $idx
494  );
495 
496  $feedback .= '<td>'. $fb . '</td>';
497 
498  $matchedIndexes[$idx] = $idx;
499 
500  break;
501  }
502  }
503 
504  $feedback .= '</tr>';
505  }
506 
507  $feedback .= '</tbody></table>';
508 
509  return $this->object->prepareTextareaOutput($feedback, TRUE);
510  }
511 
522  {
523  return array();
524  }
525 
536  {
537  return array();
538  }
539 
548  public function getAggregatedAnswersView($relevant_answers)
549  {
550  $errortext = $this->object->getErrorText();
551 
552  $passdata = array(); // Regroup answers into units of passes.
553  foreach($relevant_answers as $answer_chosen)
554  {
555  $passdata[$answer_chosen['active_fi'].'-'. $answer_chosen['pass']][$answer_chosen['value2']][] = $answer_chosen['value1'];
556  }
557 
558  $html = '';
559  foreach($passdata as $key => $pass)
560  {
561  $passdata[$key] = $this->object->createErrorTextOutput($pass);
562  $html .= $passdata[$key] . '<hr /><br />';
563  }
564 
565  return $html;
566  }
567 }
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
$errors
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
writePostData()
Evaluates a posted edit form and writes the form data in the question object.
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
$_POST['username']
Definition: cron.php:12
setValue($a_value)
Set Value.
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
This class represents a property form user interface.
$_GET["client_id"]
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
This class represents a section header in a property form.
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
setValue($a_value)
Set Value.
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
addItem($a_item)
Add Item (Property, SectionHeader).
getQuestionTemplate()
get question template
__construct($id=-1)
assErrorTextGUI constructor
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
populateTaxonomyFormSection(ilPropertyFormGUI $form)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
allowDecimals($a_value)
Toggle Decimals.
getTestOutput( $active_id, $pass=NULL, $is_postponed=FALSE, $use_post_solutions=FALSE, $show_feedback=FALSE)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
getILIASPage($html="")
Returns the ILIAS Page around a question.
This class represents a number property in a property form.
special template class to simplify handling of ITX/PEAR
Class for error text questions.
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
The assErrorTextGUI class encapsulates the GUI representation for error text questions.
Basic GUI class for assessment questions.
setErrorMessage($errormessage)
_getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
analyze()
Parse the error text.
This class represents a text area property in a property form.
addBackTab(ilTabsGUI $ilTabs)
This class represents a key value pair wizard property in a property form.
getSpecificFeedbackOutput($active_id, $pass)
Interface ilGuiAnswerScoringAdjustable.
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.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
Interface ilGuiQuestionScoringAdjustable.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.