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
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7
8require_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';
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
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
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}
sprintf('%.4f', $callTime)
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
The assErrorTextGUI class encapsulates the GUI representation for error text questions.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getTestOutput( $active_id, $pass, $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...
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
__construct($id=-1)
assErrorTextGUI constructor
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.
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
getSpecificFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
analyze()
Parse the error text.
Class for error text questions.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
setErrorMessage($errormessage)
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
addBackTab(ilTabsGUI $ilTabs)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
This class represents a key value pair wizard property in a property form.
This class represents a section header in a property form.
This class represents a number property in a property form.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
special template class to simplify handling of ITX/PEAR
This class represents a text area property in a property form.
$html
Definition: example_001.php:87
$header
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$url
Definition: shib_logout.php:72
$errors