ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 
49  protected function writePostData($always = false)
50  {
51  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
52  if (!$hasErrors)
53  {
54  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
58  $this->saveTaxonomyAssignments();
59  return 0;
60  }
61  return 1;
62  }
63 
65  {
66  if (is_array( $_POST['errordata']['key'] ))
67  {
68  $this->object->flushErrorData();
69  foreach ($_POST['errordata']['key'] as $idx => $val)
70  {
71  $this->object->addErrorData( $val,
72  $_POST['errordata']['value'][$idx],
73  $_POST['errordata']['points'][$idx]
74  );
75  }
76  }
77  }
78 
80  {
81  $questiontext = $_POST["question"];
82  $this->object->setQuestion( $questiontext );
83  $this->object->setErrorText( $_POST["errortext"] );
84  $points_wrong = str_replace( ",", ".", $_POST["points_wrong"] );
85  if (strlen( $points_wrong ) == 0)
86  $points_wrong = -1.0;
87  $this->object->setPointsWrong( $points_wrong );
88 
89  if (!$this->object->getSelfAssessmentEditingMode())
90  {
91  $this->object->setTextSize( $_POST["textsize"] );
92  }
93  }
94 
102  public function editQuestion($checkonly = FALSE)
103  {
104  $save = $this->isSaveCommand();
105  $this->getQuestionTemplate();
106 
107  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
108  $form = new ilPropertyFormGUI();
109  $this->editForm = $form;
110 
111  $form->setFormAction($this->ctrl->getFormAction($this));
112  $form->setTitle($this->outQuestionType());
113  $form->setMultipart(FALSE);
114  $form->setTableWidth("100%");
115  $form->setId("orderinghorizontal");
116 
117  $this->addBasicQuestionFormProperties( $form );
118 
119  $this->populateQuestionSpecificFormPart( $form );
120 
121  if (count($this->object->getErrorData()) || $checkonly)
122  {
123  $this->populateAnswerSpecificFormPart( $form );
124  }
125 
126  $this->populateTaxonomyFormSection($form);
127 
128  $form->addCommandButton("analyze", $this->lng->txt('analyze_errortext'));
129  $this->addQuestionFormCommandButtons($form);
130 
131  $errors = false;
132 
133  if ($save)
134  {
135  $form->setValuesByPost();
136  $errors = !$form->checkInput();
137  $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
138  if ($errors) $checkonly = false;
139  }
140 
141  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
142  return $errors;
143  }
144 
150  {
152  $header->setTitle( $this->lng->txt( "errors_section" ) );
153  $form->addItem( $header );
154 
155  include_once "./Modules/TestQuestionPool/classes/class.ilErrorTextWizardInputGUI.php";
156  $errordata = new ilErrorTextWizardInputGUI($this->lng->txt( "errors" ), "errordata");
157  $errordata->setKeyName( $this->lng->txt( 'text_wrong' ) );
158  $errordata->setValueName( $this->lng->txt( 'text_correct' ) );
159  $errordata->setValues( $this->object->getErrorData() );
160  $form->addItem( $errordata );
161 
162  // points for wrong selection
163  $points_wrong = new ilNumberInputGUI($this->lng->txt( "points_wrong" ), "points_wrong");
164  $points_wrong->allowDecimals(true);
165  $points_wrong->setMaxValue(0);
166  $points_wrong->setMaxvalueShouldBeLess(true);
167  $points_wrong->setValue( $this->object->getPointsWrong() );
168  $points_wrong->setInfo( $this->lng->txt( "points_wrong_info" ) );
169  $points_wrong->setSize( 6 );
170  $points_wrong->setRequired( true );
171  $form->addItem( $points_wrong );
172  return $form;
173  }
174 
180  {
181  // errortext
182  $errortext = new ilTextAreaInputGUI($this->lng->txt( "errortext" ), "errortext");
183  $errortext->setValue( $this->object->getErrorText() );
184  $errortext->setRequired( TRUE );
185  $errortext->setInfo( $this->lng->txt( "errortext_info" ) );
186  $errortext->setRows( 10 );
187  $errortext->setCols( 80 );
188  $form->addItem( $errortext );
189 
190  if (!$this->object->getSelfAssessmentEditingMode())
191  {
192  // textsize
193  $textsize = new ilNumberInputGUI($this->lng->txt( "textsize" ), "textsize");
194  $textsize->setValue( strlen( $this->object->getTextSize() ) ? $this->object->getTextSize() : 100.0 );
195  $textsize->setInfo( $this->lng->txt( "textsize_errortext_info" ) );
196  $textsize->setSize( 6 );
197  $textsize->setSuffix( "%" );
198  $textsize->setMinValue( 10 );
199  $textsize->setRequired( true );
200  $form->addItem( $textsize );
201  }
202  }
203 
207  public function analyze()
208  {
209  $this->writePostData(true);
210  $this->object->setErrorData($this->object->getErrorsFromText($_POST['errortext']));
211  $this->editQuestion();
212  }
213 
233  $active_id, $pass = NULL,
234  $graphicalOutput = FALSE,
235  $result_output = FALSE,
236  $show_question_only = TRUE,
237  $show_feedback = FALSE,
238  $show_correct_solution = FALSE,
239  $show_manual_scoring = FALSE,
240  $show_question_text = TRUE
241  )
242  {
243  // get the solution of the user for the active pass or from the last pass if allowed
244  $template = new ilTemplate("tpl.il_as_qpl_errortext_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
245 
246  $selections = array();
247  if (($active_id > 0) && (!$show_correct_solution)) {
248 
249  /* Retrieve tst_solutions entries. */
250  $reached_points = $this->object->getReachedPoints($active_id, $pass);
251  $solutions =& $this->object->getSolutionValues($active_id, $pass);
252  if (is_array($solutions)) {
253  foreach ($solutions as $solution) {
254  array_push($selections, (int) $solution['value1']);
255  }
256  $errortext_value = join(",", $selections);
257  }
258  }
259  else {
260  $selections = $this->object->getBestSelection();
261  $reached_points = $this->object->getPoints();
262  }
263 
264  if ($result_output) {
265  $resulttext = ($reached_points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
266  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $reached_points));
267  }
268 
269  if ($this->object->getTextSize() >= 10)
270  $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
271 
272  if ($show_question_text==true)
273  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), TRUE));
274 
275  $errortext = $this->object->createErrorTextOutput($selections, $graphicalOutput, $show_correct_solution, false);
276 
277  $template->setVariable("ERRORTEXT", $errortext);
278  $questionoutput = $template->get();
279 
280  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
281 
282  $feedback = '';
283  if($show_feedback)
284  {
285  if( !$this->isTestPresentationContext() )
286  {
287  $fb = $this->getGenericFeedbackOutput($active_id, $pass);
288  $feedback .= strlen($fb) ? $fb : '';
289  }
290 
291  $fb = $this->getSpecificFeedbackOutput($active_id, $pass);
292  $feedback .= strlen($fb) ? $fb : '';
293  }
294  if (strlen($feedback))
295  {
296  $cssClass = ( $this->hasCorrectSolution($active_id, $pass) ?
298  );
299 
300  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
301  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
302  }
303 
304  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
305 
306  $solutionoutput = $solutiontemplate->get();
307  if (!$show_question_only)
308  {
309  // get page object output
310  $solutionoutput = $this->getILIASPage($solutionoutput);
311  }
312  return $solutionoutput;
313  }
314 
315  function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
316  {
317  $selections = is_object($this->getPreviewSession()) ? (array)$this->getPreviewSession()->getParticipantsSolution() : array();
318 
319  $template = new ilTemplate("tpl.il_as_qpl_errortext_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
320  if ($this->object->getTextSize() >= 10) $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
321  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), TRUE));
322  $errortext = $this->object->createErrorTextOutput($selections);
323  $template->setVariable("ERRORTEXT", $errortext);
324  $template->setVariable("ERRORTEXT_ID", "qst_" . $this->object->getId());
325  $questionoutput = $template->get();
326  if (!$show_question_only)
327  {
328  // get page object output
329  $questionoutput = $this->getILIASPage($questionoutput);
330  }
331  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/errortext.js");
332  return $questionoutput;
333  }
334 
335  function getTestOutput(
336  $active_id,
337  // hey: prevPassSolutions - will be always available from now on
338  $pass,
339  // hey.
340  $is_postponed = FALSE,
341  $use_post_solutions = FALSE,
342  $show_feedback = FALSE
343  )
344  {
345  // generate the question output
346  $template = new ilTemplate("tpl.il_as_qpl_errortext_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
347  if ($active_id)
348  {
349  // hey: prevPassSolutions - obsolete due to central check
350  #$solutions = NULL;
351  #include_once "./Modules/Test/classes/class.ilObjTest.php";
352  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
353  #{
354  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
355  #}
356  $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
357  // hey.
358  }
359  $errortext_value = "";
360  $selections = array();
361  if (is_array($solutions))
362  {
363  foreach ($solutions as $solution)
364  {
365  array_push($selections, $solution['value1']);
366  }
367  $errortext_value = join(",", $selections);
368  }
369  if ($this->object->getTextSize() >= 10) $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
370  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($this->object->getQuestion(), TRUE));
371  $errortext = $this->object->createErrorTextOutput($selections);
372  $this->ctrl->setParameterByClass($this->getTargetGuiClass(), 'errorvalue', '');
373  $template->setVariable("ERRORTEXT", $errortext);
374  $template->setVariable("ERRORTEXT_ID", "qst_" . $this->object->getId());
375  $template->setVariable("ERRORTEXT_VALUE", $errortext_value);
376 
377  $questionoutput = $template->get();
378  if (!$show_question_only)
379  {
380  // get page object output
381  $questionoutput = $this->getILIASPage($questionoutput);
382  }
383  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/errortext.js");
384  $questionoutput = $template->get();
385  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
386  return $pageoutput;
387  }
388 
396  function setQuestionTabs()
397  {
398  global $rbacsystem, $ilTabs;
399 
400  $ilTabs->clearTargets();
401 
402  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
403  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
404  $q_type = $this->object->getQuestionType();
405 
406  if (strlen($q_type))
407  {
408  $classname = $q_type . "GUI";
409  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
410  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
411  }
412 
413  if ($_GET["q_id"])
414  {
415  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
416  {
417  // edit page
418  $ilTabs->addTarget("edit_page",
419  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
420  array("edit", "insert", "exec_pg"),
421  "", "", $force_active);
422  }
423 
424  $this->addTab_QuestionPreview($ilTabs);
425  }
426 
427  $force_active = false;
428  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
429  {
430  $url = "";
431  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
432  // edit question properties
433  $ilTabs->addTarget("edit_question",
434  $url,
435  array("editQuestion", "save", "saveEdit", "analyze", "originalSyncForm"),
436  $classname, "", $force_active);
437  }
438 
439  // add tab for question feedback within common class assQuestionGUI
440  $this->addTab_QuestionFeedback($ilTabs);
441 
442  // add tab for question hint within common class assQuestionGUI
443  $this->addTab_QuestionHints($ilTabs);
444 
445  // add tab for question's suggested solution within common class assQuestionGUI
446  $this->addTab_SuggestedSolution($ilTabs, $classname);
447 
448  // Assessment of questions sub menu entry
449  if ($_GET["q_id"])
450  {
451  $ilTabs->addTarget("statistics",
452  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
453  array("assessment"),
454  $classname, "");
455  }
456 
457  $this->addBackTab($ilTabs);
458  }
459 
460  function getSpecificFeedbackOutput($active_id, $pass)
461  {
462  $selection = $this->object->getBestSelection(false);
463 
464  if( !$this->object->feedbackOBJ->specificAnswerFeedbackExists(array_keys($selection)) )
465  {
466  return '';
467  }
468 
469  $feedback = '<table class="test_specific_feedback"><tbody>';
470 
471  $elements = array();
472  foreach(preg_split("/[\n\r]+/", $this->object->errortext) as $line)
473  {
474  $elements = array_merge( $elements, preg_split("/\s+/", $line));
475  }
476 
477  $matchedIndexes = array();
478 
479  $i = 0;
480  foreach ($selection as $index => $answer)
481  {
482  $element = array();
483  foreach($answer as $answerPartIndex)
484  {
485  $element[] = $elements[$answerPartIndex];
486  }
487 
488  $element = implode(' ', $element);
489  $element = str_replace(array('((', '))', '#'), array('', '', ''), $element);
490 
491  $ordinal = $index + 1;
492 
493  $feedback .= '<tr>';
494 
495  $feedback .= '<td class="text-nowrap">' . $ordinal . '. ' . $element . ':</td>';
496 
497  foreach ($this->object->getErrorData() as $idx => $ans)
498  {
499  if( isset($matchedIndexes[$idx]) )
500  {
501  continue;
502  }
503 
504  if ( preg_match('/'.preg_quote($ans->text_wrong, '/').'/', $element) )
505  {
506  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
507  $this->object->getId(), $idx
508  );
509 
510  $feedback .= '<td>'. $fb . '</td>';
511 
512  $matchedIndexes[$idx] = $idx;
513 
514  break;
515  }
516  }
517 
518  $feedback .= '</tr>';
519  }
520 
521  $feedback .= '</tbody></table>';
522 
523  return $this->object->prepareTextareaOutput($feedback, TRUE);
524  }
525 
536  {
537  return array();
538  }
539 
550  {
551  return array();
552  }
553 
562  public function getAggregatedAnswersView($relevant_answers)
563  {
564  $errortext = $this->object->getErrorText();
565 
566  $passdata = array(); // Regroup answers into units of passes.
567  foreach($relevant_answers as $answer_chosen)
568  {
569  $passdata[$answer_chosen['active_fi'].'-'. $answer_chosen['pass']][$answer_chosen['value2']][] = $answer_chosen['value1'];
570  }
571 
572  $html = '';
573  foreach($passdata as $key => $pass)
574  {
575  $passdata[$key] = $this->object->createErrorTextOutput($pass);
576  $html .= $passdata[$key] . '<hr /><br />';
577  }
578 
579  return $html;
580  }
581 }
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
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"]
This class represents a section header in a property form.
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
setValue($a_value)
Set Value.
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
writePostData($always=false)
{}
addItem($a_item)
Add Item (Property, SectionHeader).
$url
Definition: shib_logout.php:72
getTestOutput( $active_id, $pass, $is_postponed=FALSE, $use_post_solutions=FALSE, $show_feedback=FALSE)
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.
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)
$header
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)
Create styles array
The data for the language used.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
analyze()
Parse the error text.
$errors
Create new PHPExcel object
obj_idprivate
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.
$_POST["username"]
$html
Definition: example_001.php:87
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.