ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7require_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';
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';
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
130 {
131 return true;
132 }
133
147 public function getSolutionOutput(
148 $active_id,
149 $pass = null,
150 $graphicalOutput = false,
151 $result_output = false,
152 $show_question_only = true,
153 $show_feedback = false,
154 $show_correct_solution = false,
155 $show_manual_scoring = false,
156 $show_question_text = true
157 ) {
158 // get the solution of the user for the active pass or from the last pass if allowed
159 $solutions = array();
160 if (($active_id > 0) && (!$show_correct_solution)) {
161 $solutions = $this->object->getSolutionValues($active_id, $pass, !$this->getUseIntermediateSolution());
162 } else {
163 $rank = array();
164 foreach ($this->object->answers as $answer) {
165 if ($answer->getPoints() > 0) {
166 if (!is_array($rank[$answer->getPoints()])) {
167 $rank[$answer->getPoints()] = array();
168 }
169 array_push($rank[$answer->getPoints()], $answer->getAnswertext());
170 }
171 }
172 krsort($rank, SORT_NUMERIC);
173 foreach ($rank as $index => $bestsolutions) {
174 array_push($solutions, array("value1" => join(",", $bestsolutions), "points" => $index));
175 }
176 }
177
178 // generate the question output
179 include_once "./Services/UICore/classes/class.ilTemplate.php";
180 $template = new ilTemplate("tpl.il_as_qpl_textsubset_output_solution.html", true, true, "Modules/TestQuestionPool");
181 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
182 $available_answers = &$this->object->getAvailableAnswers();
183 for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++) {
184 if ((!$test_id) && (strcmp($solutions[$i]["value1"], "") == 0)) {
185 } else {
186 if (($active_id > 0) && (!$show_correct_solution)) {
187 if ($graphicalOutput) {
188 // output of ok/not ok icons for user entered solutions
189 $index = $this->object->isAnswerCorrect($available_answers, $solutions[$i]["value1"]);
190 $correct = false;
191 if ($index !== false) {
192 unset($available_answers[$index]);
193 $correct = true;
194 }
195 if ($correct) {
196 $template->setCurrentBlock("icon_ok");
197 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
198 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
199 $template->parseCurrentBlock();
200 } else {
201 $template->setCurrentBlock("icon_ok");
202 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
203 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
204 $template->parseCurrentBlock();
205 }
206 }
207 }
208 $template->setCurrentBlock("textsubset_row");
209 $template->setVariable("SOLUTION", $solutions[$i]["value1"]);
210 $template->setVariable("COUNTER", $i + 1);
211 if ($result_output) {
212 $points = $solutions[$i]["points"];
213 $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
214 $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
215 }
216 $template->parseCurrentBlock();
217 }
218 }
219 $questiontext = $this->object->getQuestion();
220 if ($show_question_text == true) {
221 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
222 }
223 $questionoutput = $template->get();
224 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
225 if (strlen($feedback)) {
226 $cssClass = (
227 $this->hasCorrectSolution($active_id, $pass) ?
229 );
230
231 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
232 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
233 }
234 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
235
236 $solutionoutput = $solutiontemplate->get();
237 if (!$show_question_only) {
238 // get page object output
239 $solutionoutput = $this->getILIASPage($solutionoutput);
240 }
241 return $solutionoutput;
242 }
243
244 public function getPreview($show_question_only = false, $showInlineFeedback = false)
245 {
246 $solutions = is_object($this->getPreviewSession()) ? (array) $this->getPreviewSession()->getParticipantsSolution() : array();
247 // generate the question output
248 include_once "./Services/UICore/classes/class.ilTemplate.php";
249 $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", true, true, "Modules/TestQuestionPool");
250 $width = $this->object->getMaxTextboxWidth();
251 for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++) {
252 $template->setCurrentBlock("textsubset_row");
253 foreach ($solutions as $idx => $solution_value) {
254 if ($idx == $i) {
255 $template->setVariable("TEXTFIELD_VALUE", " value=\"" . $solution_value . "\"");
256 }
257 }
258 $template->setVariable("COUNTER", $i + 1);
259 $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i + 1));
260 $template->setVariable("TEXTFIELD_SIZE", $width);
261 $template->parseCurrentBlock();
262 }
263 $questiontext = $this->object->getQuestion();
264 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
265 $questionoutput = $template->get();
266 if (!$show_question_only) {
267 // get page object output
268 $questionoutput = $this->getILIASPage($questionoutput);
269 }
270 return $questionoutput;
271 }
272
273 public function getTestOutput($active_id, $pass = null, $is_postponed = false, $use_post_solutions = false, $inlineFeedback = false)
274 {
275 // get the solution of the user for the active pass or from the last pass if allowed
276 $user_solution = "";
277 if ($active_id) {
278 $solutions = null;
279 // hey: prevPassSolutions - obsolete due to central check
280 #include_once "./Modules/Test/classes/class.ilObjTest.php";
281 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
282 #{
283 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
284 #}
285 // hey.
286 $solutions = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
287 }
288
289 // generate the question output
290 include_once "./Services/UICore/classes/class.ilTemplate.php";
291 $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", true, true, "Modules/TestQuestionPool");
292 $width = $this->object->getMaxTextboxWidth();
293 for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++) {
294 $template->setCurrentBlock("textsubset_row");
295 foreach ($solutions as $idx => $solution_value) {
296 if ($idx == $i) {
297 $template->setVariable("TEXTFIELD_VALUE", " value=\"" . ilUtil::prepareFormOutput($solution_value["value1"]) . "\"");
298 }
299 }
300 $template->setVariable("COUNTER", $i + 1);
301 $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i + 1));
302 $template->setVariable("TEXTFIELD_SIZE", $width);
303 $template->parseCurrentBlock();
304 }
305 $questiontext = $this->object->getQuestion();
306 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
307 $questionoutput = $template->get();
308 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
309 return $pageoutput;
310 }
311
319 public function setQuestionTabs()
320 {
321 global $DIC;
322 $rbacsystem = $DIC['rbacsystem'];
323 $ilTabs = $DIC['ilTabs'];
324
325 $ilTabs->clearTargets();
326
327 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
328 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
329 $q_type = $this->object->getQuestionType();
330
331 if (strlen($q_type)) {
332 $classname = $q_type . "GUI";
333 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
334 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
335 }
336
337 if ($_GET["q_id"]) {
338 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
339 // edit page
340 $ilTabs->addTarget(
341 "edit_page",
342 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
343 array("edit", "insert", "exec_pg"),
344 "",
345 "",
346 $force_active
347 );
348 }
349
350 $this->addTab_QuestionPreview($ilTabs);
351 }
352
353 $force_active = false;
354 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
355 $url = "";
356 if ($classname) {
357 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
358 }
359 // edit question properties
360 $ilTabs->addTarget(
361 "edit_question",
362 $url,
363 array("editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "originalSyncForm"),
364 $classname,
365 "",
366 $force_active
367 );
368 }
369
370 // add tab for question feedback within common class assQuestionGUI
371 $this->addTab_QuestionFeedback($ilTabs);
372
373 // add tab for question hint within common class assQuestionGUI
374 $this->addTab_QuestionHints($ilTabs);
375
376 // add tab for question's suggested solution within common class assQuestionGUI
377 $this->addTab_SuggestedSolution($ilTabs, $classname);
378
379 // Assessment of questions sub menu entry
380 if ($_GET["q_id"]) {
381 $ilTabs->addTarget(
382 "statistics",
383 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
384 array("assessment"),
385 $classname,
386 ""
387 );
388 }
389
390 $this->addBackTab($ilTabs);
391 }
392
393 public function getSpecificFeedbackOutput($userSolution)
394 {
395 $output = "";
396 return $this->object->prepareTextareaOutput($output, true);
397 }
398
400 {
401 $this->object->setCorrectAnswers($_POST["correctanswers"]);
402 $this->object->setTextRating($_POST["text_rating"]);
403 }
404
406 {
407 // Delete all existing answers and create new answers from the form data
408 $this->object->flushAnswers();
409 foreach ($_POST['answers']['answer'] as $index => $answer) {
410 $answertext = $answer;
411 $this->object->addAnswer($answertext, $_POST['answers']['points'][$index], $index);
412 }
413 }
414
416 {
417 // number of requested answers
418 $correctanswers = new ilNumberInputGUI($this->lng->txt("nr_of_correct_answers"), "correctanswers");
419 $correctanswers->setMinValue(1);
420 $correctanswers->setDecimals(0);
421 $correctanswers->setSize(3);
422 $correctanswers->setValue($this->object->getCorrectAnswers());
423 $correctanswers->setRequired(true);
424 $form->addItem($correctanswers);
425
426 // maximum available points
427 $points = new ilNumberInputGUI($this->lng->txt("maximum_points"), "points");
428 $points->setMinValue(0.0);
429 $points->setMinvalueShouldBeGreater(true);
430 $points->setSize(6);
431 $points->setDisabled(true);
432 $points->allowDecimals(true);
433 $points->setValue($this->object->getMaximumPoints());
434 $points->setRequired(false);
435 $form->addItem($points);
436
437 // text rating
438 $textrating = new ilSelectInputGUI($this->lng->txt("text_rating"), "text_rating");
439 $text_options = array(
440 "ci" => $this->lng->txt("cloze_textgap_case_insensitive"),
441 "cs" => $this->lng->txt("cloze_textgap_case_sensitive")
442 );
443 if (!$this->object->getSelfAssessmentEditingMode()) {
444 $text_options["l1"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "1");
445 $text_options["l2"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "2");
446 $text_options["l3"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "3");
447 $text_options["l4"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "4");
448 $text_options["l5"] = sprintf($this->lng->txt("cloze_textgap_levenshtein_of"), "5");
449 }
450 $textrating->setOptions($text_options);
451 $textrating->setValue($this->object->getTextRating());
452 $form->addItem($textrating);
453 return $form;
454 }
455
457 {
458 // Choices
459 include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
460 $choices = new ilAnswerWizardInputGUI($this->lng->txt("answers"), "answers");
461 $choices->setRequired(true);
462 $choices->setQuestionObject($this->object);
463 $choices->setSingleline(true);
464 $choices->setAllowMove(false);
465 $choices->setMinValue(0.0);
466 if ($this->object->getAnswerCount() == 0) {
467 $this->object->addAnswer("", 0, 0);
468 }
469 $choices->setValues($this->object->getAnswers());
470 $form->addItem($choices);
471 return $form;
472 }
473
474
485 {
486 return array();
487 }
488
499 {
500 return array();
501 }
502
511 public function getAggregatedAnswersView($relevant_answers)
512 {
513 return $this->renderAggregateView(
514 $this->aggregateAnswers($relevant_answers)
515 )->get();
516 }
517
518 public function aggregateAnswers($relevant_answers_chosen)
519 {
520 $aggregate = array();
521
522 foreach ($relevant_answers_chosen as $relevant_answer) {
523 if (array_key_exists($relevant_answer['value1'], $aggregate)) {
524 $aggregate[$relevant_answer['value1']]++;
525 } else {
526 $aggregate[$relevant_answer['value1']] = 1;
527 }
528 }
529 return $aggregate;
530 }
531
537 public function renderAggregateView($aggregate)
538 {
539 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
540
541 foreach ($aggregate as $key => $value) {
542 $tpl->setCurrentBlock('aggregaterow');
543 $tpl->setVariable('OPTION', $key);
544 $tpl->setVariable('COUNT', $value);
545 $tpl->parseCurrentBlock();
546 }
547 return $tpl;
548 }
549
550 public function getAnswersFrequency($relevantAnswers, $questionIndex)
551 {
552 $answers = array();
553
554 foreach ($relevantAnswers as $ans) {
555 if (!isset($answers[$ans['value1']])) {
556 $answers[$ans['value1']] = array(
557 'answer' => $ans['value1'], 'frequency' => 0
558 );
559 }
560
561 $answers[$ans['value1']]['frequency']++;
562 }
563
564 return $answers;
565 }
566
568 {
569 // Choices
570 require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssAnswerCorrectionsInputGUI.php';
571 $choices = new ilAssAnswerCorrectionsInputGUI($this->lng->txt("answers"), "answers");
572 $choices->setRequired(true);
573 $choices->setQuestionObject($this->object);
574 $choices->setValues($this->object->getAnswers());
575 $form->addItem($choices);
576
577 return $form;
578 }
579
584 {
585 $points = $form->getInput('answers')['points'];
586
587 foreach ($this->object->getAnswers() as $index => $answer) {
588 /* @var ASS_AnswerBinaryStateImage $answer */
589 $answer->setPoints((float) $points[$index]);
590 }
591 }
592}
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
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="", $inlineFeedbackEnabled=false)
output question page
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
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)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
Multiple choice question GUI representation.
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
getTestOutput($active_id, $pass=null, $is_postponed=false, $use_post_solutions=false, $inlineFeedback=false)
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
__construct($id=-1)
assTextSubsetGUI constructor
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
addanswers()
Add a new answer.
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.
getPreview($show_question_only=false, $showInlineFeedback=false)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
setQuestionTabs()
Sets the ILIAS tabs for this question type.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
aggregateAnswers($relevant_answers_chosen)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
removeanswers()
Remove an answer.
getAnswersFrequency($relevantAnswers, $questionIndex)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
Class for TextSubset questions.
This class represents a single choice wizard property in a property form.
This class represents a number property in a property form.
This class represents a property form user interface.
This class represents a selection list property in a property form.
special template class to simplify handling of ITX/PEAR
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
$template
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
if(!array_key_exists('StateId', $_REQUEST)) $id
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$index
Definition: metadata.php:60
$errors
Definition: index.php:6
$url
if(isset($_POST['submit'])) $form
global $DIC
Definition: saml.php:7