ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
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
24{
32 public function __construct($id = -1)
33 {
34 parent::__construct();
35 require_once './Modules/TestQuestionPool/classes/class.assTextSubset.php';
36 $this->object = new assTextSubset();
37 if ($id >= 0)
38 {
39 $this->object->loadFromDb($id);
40 }
41 }
42
50 public function writePostData($always = false)
51 {
52 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
53 if (!$hasErrors)
54 {
55 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
60 return 0;
61 }
62 return 1;
63 }
64
68 public function editQuestion($checkonly = FALSE)
69 {
70 $save = $this->isSaveCommand();
71 $this->getQuestionTemplate();
72
73 require_once './Services/Form/classes/class.ilPropertyFormGUI.php';
74 $form = new ilPropertyFormGUI();
75 $form->setFormAction($this->ctrl->getFormAction($this));
76 $form->setTitle($this->outQuestionType());
77 $form->setMultipart(FALSE);
78 $form->setTableWidth("100%");
79 $form->setId("asstextsubset");
80
83 $this->populateAnswerSpecificFormPart( $form );
84 $this->populateTaxonomyFormSection($form);
86
87 $errors = false;
88 if ($save)
89 {
90 $form->setValuesByPost();
91 $points = $form->getItemByPostVar('points');
92 $points->setValue($this->object->getMaximumPoints());
93 $errors = !$form->checkInput();
94 $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
95 if ($errors) $checkonly = false;
96 }
97
98 if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
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
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 {
149 // get the solution of the user for the active pass or from the last pass if allowed
150 $solutions = array();
151 if (($active_id > 0) && (!$show_correct_solution))
152 {
153 $solutions =& $this->object->getSolutionValues($active_id, $pass);
154 }
155 else
156 {
157 $rank = array();
158 foreach ($this->object->answers as $answer)
159 {
160 if ($answer->getPoints() > 0)
161 {
162 if (!is_array($rank[$answer->getPoints()]))
163 {
164 $rank[$answer->getPoints()] = array();
165 }
166 array_push($rank[$answer->getPoints()], $answer->getAnswertext());
167 }
168 }
169 krsort($rank, SORT_NUMERIC);
170 foreach ($rank as $index => $bestsolutions)
171 {
172 array_push($solutions, array("value1" => join(",", $bestsolutions), "points" => $index));
173 }
174 }
175
176 // generate the question output
177 include_once "./Services/UICore/classes/class.ilTemplate.php";
178 $template = new ilTemplate("tpl.il_as_qpl_textsubset_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
179 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
180 $available_answers =& $this->object->getAvailableAnswers();
181 for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
182 {
183 if ((!$test_id) && (strcmp($solutions[$i]["value1"], "") == 0))
184 {
185 }
186 else
187 {
188 if (($active_id > 0) && (!$show_correct_solution))
189 {
190 if ($graphicalOutput)
191 {
192 // output of ok/not ok icons for user entered solutions
193 $index = $this->object->isAnswerCorrect($available_answers, $solutions[$i]["value1"]);
194 $correct = FALSE;
195 if ($index !== FALSE)
196 {
197 unset($available_answers[$index]);
198 $correct = TRUE;
199 }
200 if ($correct)
201 {
202 $template->setCurrentBlock("icon_ok");
203 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
204 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
205 $template->parseCurrentBlock();
206 }
207 else
208 {
209 $template->setCurrentBlock("icon_ok");
210 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
211 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
212 $template->parseCurrentBlock();
213 }
214 }
215 }
216 $template->setCurrentBlock("textsubset_row");
217 $template->setVariable("SOLUTION", $solutions[$i]["value1"]);
218 $template->setVariable("COUNTER", $i+1);
219 if ($result_output)
220 {
221 $points = $solutions[$i]["points"];
222 $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
223 $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
224 }
225 $template->parseCurrentBlock();
226 }
227 }
228 $questiontext = $this->object->getQuestion();
229 if ($show_question_text==true)
230 {
231 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
232 }
233 $questionoutput = $template->get();
234 $feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
235 if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true));
236 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
237
238 $solutionoutput = $solutiontemplate->get();
239 if (!$show_question_only)
240 {
241 // get page object output
242 $solutionoutput = $this->getILIASPage($solutionoutput);
243 }
244 return $solutionoutput;
245 }
246
247 function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
248 {
249 $solutions = is_object($this->getPreviewSession()) ? (array)$this->getPreviewSession()->getParticipantsSolution() : array();
250 // generate the question output
251 include_once "./Services/UICore/classes/class.ilTemplate.php";
252 $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
253 $width = $this->object->getMaxTextboxWidth();
254 for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
255 {
256 $template->setCurrentBlock("textsubset_row");
257 foreach ($solutions as $idx => $solution_value)
258 {
259 if ($idx == $i)
260 {
261 $template->setVariable("TEXTFIELD_VALUE", " value=\"" . $solution_value."\"");
262 }
263 }
264 $template->setVariable("COUNTER", $i+1);
265 $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
266 $template->setVariable("TEXTFIELD_SIZE", $width);
267 $template->parseCurrentBlock();
268 }
269 $questiontext = $this->object->getQuestion();
270 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
271 $questionoutput = $template->get();
272 if (!$show_question_only)
273 {
274 // get page object output
275 $questionoutput = $this->getILIASPage($questionoutput);
276 }
277 return $questionoutput;
278 }
279
280 function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
281 {
282 // get the solution of the user for the active pass or from the last pass if allowed
283 $user_solution = "";
284 if ($active_id)
285 {
286 $solutions = NULL;
287 include_once "./Modules/Test/classes/class.ilObjTest.php";
288 if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
289 {
290 if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
291 }
292 $solutions =& $this->object->getSolutionValues($active_id, $pass);
293 }
294
295 // generate the question output
296 include_once "./Services/UICore/classes/class.ilTemplate.php";
297 $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
298 $width = $this->object->getMaxTextboxWidth();
299 for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
300 {
301 $template->setCurrentBlock("textsubset_row");
302 foreach ($solutions as $idx => $solution_value)
303 {
304 if ($idx == $i)
305 {
306 $template->setVariable("TEXTFIELD_VALUE", " value=\"" . ilUtil::prepareFormOutput($solution_value["value1"])."\"");
307 }
308 }
309 $template->setVariable("COUNTER", $i+1);
310 $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
311 $template->setVariable("TEXTFIELD_SIZE", $width);
312 $template->parseCurrentBlock();
313 }
314 $questiontext = $this->object->getQuestion();
315 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
316 $questionoutput = $template->get();
317 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
318 return $pageoutput;
319 }
320
329 {
330 global $rbacsystem, $ilTabs;
331
332 $ilTabs->clearTargets();
333
334 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
335 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
336 $q_type = $this->object->getQuestionType();
337
338 if (strlen($q_type))
339 {
340 $classname = $q_type . "GUI";
341 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
342 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
343 }
344
345 if ($_GET["q_id"])
346 {
347 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
348 {
349 // edit page
350 $ilTabs->addTarget("edit_page",
351 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
352 array("edit", "insert", "exec_pg"),
353 "", "", $force_active);
354 }
355
356 $this->addTab_QuestionPreview($ilTabs);
357 }
358
359 $force_active = false;
360 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
361 {
362 $url = "";
363 if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
364 // edit question properties
365 $ilTabs->addTarget("edit_question",
366 $url,
367 array("editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "originalSyncForm"),
368 $classname, "", $force_active);
369 }
370
371 // add tab for question feedback within common class assQuestionGUI
372 $this->addTab_QuestionFeedback($ilTabs);
373
374 // add tab for question hint within common class assQuestionGUI
375 $this->addTab_QuestionHints($ilTabs);
376
377 // add tab for question's suggested solution within common class assQuestionGUI
378 $this->addTab_SuggestedSolution($ilTabs, $classname);
379
380 // Assessment of questions sub menu entry
381 if ($_GET["q_id"])
382 {
383 $ilTabs->addTarget("statistics",
384 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
385 array("assessment"),
386 $classname, "");
387 }
388
389 $this->addBackTab($ilTabs);
390 }
391
392 function getSpecificFeedbackOutput($active_id, $pass)
393 {
394 $output = "";
395 return $this->object->prepareTextareaOutput($output, TRUE);
396 }
397
399 {
400 $this->object->setCorrectAnswers( $_POST["correctanswers"] );
401 $this->object->setTextRating( $_POST["text_rating"] );
402 }
403
405 {
406 // Delete all existing answers and create new answers from the form data
407 $this->object->flushAnswers();
408 foreach ($_POST['answers']['answer'] as $index => $answer)
409 {
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->setValue( $this->object->getMaximumPoints() );
433 $points->setRequired( false );
434 $form->addItem( $points );
435
436 // text rating
437 $textrating = new ilSelectInputGUI($this->lng->txt( "text_rating" ), "text_rating");
438 $text_options = array(
439 "ci" => $this->lng->txt( "cloze_textgap_case_insensitive" ),
440 "cs" => $this->lng->txt( "cloze_textgap_case_sensitive" )
441 );
442 if (!$this->object->getSelfAssessmentEditingMode())
443 {
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 $choices->setValues( $this->object->getAnswers() );
469 $form->addItem( $choices );
470 return $form;
471 }
472
473
484 {
485 return array();
486 }
487
498 {
499 return array();
500 }
501
510 public function getAggregatedAnswersView($relevant_answers)
511 {
512 return $this->renderAggregateView(
513 $this->aggregateAnswers( $relevant_answers ) )->get();
514 }
515
516 public function aggregateAnswers($relevant_answers_chosen)
517 {
518 $aggregate = array();
519
520 foreach ($relevant_answers_chosen as $relevant_answer)
521 {
522 if ( array_key_exists($relevant_answer['value1'], $aggregate) )
523 {
524 $aggregate[$relevant_answer['value1']]++;
525 }
526 else
527 {
528 $aggregate[$relevant_answer['value1']] = 1;
529 }
530 }
531 return $aggregate;
532 }
533
539 public function renderAggregateView($aggregate)
540 {
541 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
542
543 foreach ($aggregate as $key => $value)
544 {
545 $tpl->setCurrentBlock( 'aggregaterow' );
546 $tpl->setVariable( 'OPTION', $key );
547 $tpl->setVariable( 'COUNT', $value );
548 $tpl->parseCurrentBlock();
549 }
550 return $tpl;
551 }
552}
$_GET["client_id"]
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
writePostData()
Evaluates a posted edit form and writes the form data in the question object.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
addBackTab(ilTabsGUI $ilTabs)
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.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
__construct($id=-1)
assTextSubsetGUI constructor
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.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
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.
getTestOutput($active_id, $pass=NULL, $is_postponed=FALSE, $use_post_solutions=FALSE)
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.
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
getSpecificFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
removeanswers()
Remove an answer.
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.
_getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
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
$_POST['username']
Definition: cron.php:12
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$errors