ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 
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 require_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  {
40  $this->object->loadFromDb($id);
41  }
42  }
43 
47  protected function writePostData($always = false)
48  {
49  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
50  if (!$hasErrors)
51  {
52  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
56  $this->saveTaxonomyAssignments();
57  return 0;
58  }
59  return 1;
60  }
61 
65  public function editQuestion($checkonly = FALSE)
66  {
67  $save = $this->isSaveCommand();
68  $this->getQuestionTemplate();
69 
70  require_once './Services/Form/classes/class.ilPropertyFormGUI.php';
71  $form = new ilPropertyFormGUI();
72  $this->editForm = $form;
73 
74  $form->setFormAction($this->ctrl->getFormAction($this));
75  $form->setTitle($this->outQuestionType());
76  $form->setMultipart(FALSE);
77  $form->setTableWidth("100%");
78  $form->setId("asstextsubset");
79 
80  $this->addBasicQuestionFormProperties($form);
81  $this->populateQuestionSpecificFormPart( $form );
82  $this->populateAnswerSpecificFormPart( $form );
83  $this->populateTaxonomyFormSection($form);
84  $this->addQuestionFormCommandButtons($form);
85 
86  $errors = false;
87  if ($save)
88  {
89  $form->setValuesByPost();
90  $points = $form->getItemByPostVar('points');
91  $points->setValue($this->object->getMaximumPoints());
92  $errors = !$form->checkInput();
93  $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
94  if ($errors) $checkonly = false;
95  }
96 
97  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
98  return $errors;
99  }
100 
104  public function addanswers()
105  {
106  $this->writePostData(true);
107  $position = key($_POST['cmd']['addanswers']);
108  $this->object->addAnswer("", 0, $position+1);
109  $this->editQuestion();
110  }
111 
115  public function removeanswers()
116  {
117  $this->writePostData(true);
118  $position = key($_POST['cmd']['removeanswers']);
119  $this->object->deleteAnswer($position);
120  $this->editQuestion();
121  }
122 
137  $active_id,
138  $pass = NULL,
139  $graphicalOutput = FALSE,
140  $result_output = FALSE,
141  $show_question_only = TRUE,
142  $show_feedback = FALSE,
143  $show_correct_solution = FALSE,
144  $show_manual_scoring = FALSE,
145  $show_question_text = TRUE
146  )
147  {
148  // get the solution of the user for the active pass or from the last pass if allowed
149  $solutions = array();
150  if (($active_id > 0) && (!$show_correct_solution))
151  {
152  $solutions =& $this->object->getSolutionValues($active_id, $pass);
153  }
154  else
155  {
156  $rank = array();
157  foreach ($this->object->answers as $answer)
158  {
159  if ($answer->getPoints() > 0)
160  {
161  if (!is_array($rank[$answer->getPoints()]))
162  {
163  $rank[$answer->getPoints()] = array();
164  }
165  array_push($rank[$answer->getPoints()], $answer->getAnswertext());
166  }
167  }
168  krsort($rank, SORT_NUMERIC);
169  foreach ($rank as $index => $bestsolutions)
170  {
171  array_push($solutions, array("value1" => join(",", $bestsolutions), "points" => $index));
172  }
173  }
174 
175  // generate the question output
176  include_once "./Services/UICore/classes/class.ilTemplate.php";
177  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
178  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
179  $available_answers =& $this->object->getAvailableAnswers();
180  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
181  {
182  if ((!$test_id) && (strcmp($solutions[$i]["value1"], "") == 0))
183  {
184  }
185  else
186  {
187  if (($active_id > 0) && (!$show_correct_solution))
188  {
189  if ($graphicalOutput)
190  {
191  // output of ok/not ok icons for user entered solutions
192  $index = $this->object->isAnswerCorrect($available_answers, $solutions[$i]["value1"]);
193  $correct = FALSE;
194  if ($index !== FALSE)
195  {
196  unset($available_answers[$index]);
197  $correct = TRUE;
198  }
199  if ($correct)
200  {
201  $template->setCurrentBlock("icon_ok");
202  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
203  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
204  $template->parseCurrentBlock();
205  }
206  else
207  {
208  $template->setCurrentBlock("icon_ok");
209  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
210  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
211  $template->parseCurrentBlock();
212  }
213  }
214  }
215  $template->setCurrentBlock("textsubset_row");
216  $template->setVariable("SOLUTION", $solutions[$i]["value1"]);
217  $template->setVariable("COUNTER", $i+1);
218  if ($result_output)
219  {
220  $points = $solutions[$i]["points"];
221  $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
222  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
223  }
224  $template->parseCurrentBlock();
225  }
226  }
227  $questiontext = $this->object->getQuestion();
228  if ($show_question_text==true)
229  {
230  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
231  }
232  $questionoutput = $template->get();
233  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
234  if (strlen($feedback))
235  {
236  $cssClass = ( $this->hasCorrectSolution($active_id, $pass) ?
238  );
239 
240  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
241  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
242  }
243  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
244 
245  $solutionoutput = $solutiontemplate->get();
246  if (!$show_question_only)
247  {
248  // get page object output
249  $solutionoutput = $this->getILIASPage($solutionoutput);
250  }
251  return $solutionoutput;
252  }
253 
254  function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
255  {
256  $solutions = is_object($this->getPreviewSession()) ? (array)$this->getPreviewSession()->getParticipantsSolution() : array();
257  // generate the question output
258  include_once "./Services/UICore/classes/class.ilTemplate.php";
259  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
260  $width = $this->object->getMaxTextboxWidth();
261  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
262  {
263  $template->setCurrentBlock("textsubset_row");
264  foreach ($solutions as $idx => $solution_value)
265  {
266  if ($idx == $i)
267  {
268  $template->setVariable("TEXTFIELD_VALUE", " value=\"" . $solution_value."\"");
269  }
270  }
271  $template->setVariable("COUNTER", $i+1);
272  $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
273  $template->setVariable("TEXTFIELD_SIZE", $width);
274  $template->parseCurrentBlock();
275  }
276  $questiontext = $this->object->getQuestion();
277  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
278  $questionoutput = $template->get();
279  if (!$show_question_only)
280  {
281  // get page object output
282  $questionoutput = $this->getILIASPage($questionoutput);
283  }
284  return $questionoutput;
285  }
286 
287  function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE, $inlineFeedback = false)
288  {
289  // get the solution of the user for the active pass or from the last pass if allowed
290  $user_solution = "";
291  if ($active_id)
292  {
293  $solutions = NULL;
294  // hey: prevPassSolutions - obsolete due to central check
295  #include_once "./Modules/Test/classes/class.ilObjTest.php";
296  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
297  #{
298  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
299  #}
300  // hey.
301  $solutions = $this->object->getUserSolutionPreferingIntermediate($active_id, $pass);
302  }
303 
304  // generate the question output
305  include_once "./Services/UICore/classes/class.ilTemplate.php";
306  $template = new ilTemplate("tpl.il_as_qpl_textsubset_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
307  $width = $this->object->getMaxTextboxWidth();
308  for ($i = 0; $i < $this->object->getCorrectAnswers(); $i++)
309  {
310  $template->setCurrentBlock("textsubset_row");
311  foreach ($solutions as $idx => $solution_value)
312  {
313  if ($idx == $i)
314  {
315  $template->setVariable("TEXTFIELD_VALUE", " value=\"" . ilUtil::prepareFormOutput($solution_value["value1"])."\"");
316  }
317  }
318  $template->setVariable("COUNTER", $i+1);
319  $template->setVariable("TEXTFIELD_ID", sprintf("%02d", $i+1));
320  $template->setVariable("TEXTFIELD_SIZE", $width);
321  $template->parseCurrentBlock();
322  }
323  $questiontext = $this->object->getQuestion();
324  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
325  $questionoutput = $template->get();
326  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
327  return $pageoutput;
328  }
329 
337  function setQuestionTabs()
338  {
339  global $rbacsystem, $ilTabs;
340 
341  $ilTabs->clearTargets();
342 
343  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
344  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
345  $q_type = $this->object->getQuestionType();
346 
347  if (strlen($q_type))
348  {
349  $classname = $q_type . "GUI";
350  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
351  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
352  }
353 
354  if ($_GET["q_id"])
355  {
356  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
357  {
358  // edit page
359  $ilTabs->addTarget("edit_page",
360  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
361  array("edit", "insert", "exec_pg"),
362  "", "", $force_active);
363  }
364 
365  $this->addTab_QuestionPreview($ilTabs);
366  }
367 
368  $force_active = false;
369  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
370  {
371  $url = "";
372  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
373  // edit question properties
374  $ilTabs->addTarget("edit_question",
375  $url,
376  array("editQuestion", "save", "saveEdit", "addanswers", "removeanswers", "originalSyncForm"),
377  $classname, "", $force_active);
378  }
379 
380  // add tab for question feedback within common class assQuestionGUI
381  $this->addTab_QuestionFeedback($ilTabs);
382 
383  // add tab for question hint within common class assQuestionGUI
384  $this->addTab_QuestionHints($ilTabs);
385 
386  // add tab for question's suggested solution within common class assQuestionGUI
387  $this->addTab_SuggestedSolution($ilTabs, $classname);
388 
389  // Assessment of questions sub menu entry
390  if ($_GET["q_id"])
391  {
392  $ilTabs->addTarget("statistics",
393  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
394  array("assessment"),
395  $classname, "");
396  }
397 
398  $this->addBackTab($ilTabs);
399  }
400 
401  function getSpecificFeedbackOutput($active_id, $pass)
402  {
403  $output = "";
404  return $this->object->prepareTextareaOutput($output, TRUE);
405  }
406 
408  {
409  $this->object->setCorrectAnswers( $_POST["correctanswers"] );
410  $this->object->setTextRating( $_POST["text_rating"] );
411  }
412 
414  {
415  // Delete all existing answers and create new answers from the form data
416  $this->object->flushAnswers();
417  foreach ($_POST['answers']['answer'] as $index => $answer)
418  {
419  $answertext = $answer;
420  $this->object->addAnswer( $answertext, $_POST['answers']['points'][$index], $index );
421  }
422  }
423 
425  {
426  // number of requested answers
427  $correctanswers = new ilNumberInputGUI($this->lng->txt( "nr_of_correct_answers" ), "correctanswers");
428  $correctanswers->setMinValue( 1 );
429  $correctanswers->setDecimals( 0 );
430  $correctanswers->setSize( 3 );
431  $correctanswers->setValue( $this->object->getCorrectAnswers() );
432  $correctanswers->setRequired( true );
433  $form->addItem( $correctanswers );
434 
435  // maximum available points
436  $points = new ilNumberInputGUI($this->lng->txt( "maximum_points" ), "points");
437  $points->setMinValue(0.0);
438  $points->setMinvalueShouldBeGreater(true);
439  $points->setSize( 6 );
440  $points->setDisabled( true );
441  $points->allowDecimals(true);
442  $points->setValue( $this->object->getMaximumPoints() );
443  $points->setRequired( false );
444  $form->addItem( $points );
445 
446  // text rating
447  $textrating = new ilSelectInputGUI($this->lng->txt( "text_rating" ), "text_rating");
448  $text_options = array(
449  "ci" => $this->lng->txt( "cloze_textgap_case_insensitive" ),
450  "cs" => $this->lng->txt( "cloze_textgap_case_sensitive" )
451  );
452  if (!$this->object->getSelfAssessmentEditingMode())
453  {
454  $text_options["l1"] = sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "1" );
455  $text_options["l2"] = sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "2" );
456  $text_options["l3"] = sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "3" );
457  $text_options["l4"] = sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "4" );
458  $text_options["l5"] = sprintf( $this->lng->txt( "cloze_textgap_levenshtein_of" ), "5" );
459  }
460  $textrating->setOptions( $text_options );
461  $textrating->setValue( $this->object->getTextRating() );
462  $form->addItem( $textrating );
463  return $form;
464  }
465 
467  {
468  // Choices
469  include_once "./Modules/TestQuestionPool/classes/class.ilAnswerWizardInputGUI.php";
470  $choices = new ilAnswerWizardInputGUI($this->lng->txt( "answers" ), "answers");
471  $choices->setRequired( true );
472  $choices->setQuestionObject( $this->object );
473  $choices->setSingleline( true );
474  $choices->setAllowMove( false );
475  $choices->setMinValue(0.0);
476  if ($this->object->getAnswerCount() == 0)
477  $this->object->addAnswer( "", 0, 0 );
478  $choices->setValues( $this->object->getAnswers() );
479  $form->addItem( $choices );
480  return $form;
481  }
482 
483 
494  {
495  return array();
496  }
497 
508  {
509  return array();
510  }
511 
520  public function getAggregatedAnswersView($relevant_answers)
521  {
522  return $this->renderAggregateView(
523  $this->aggregateAnswers( $relevant_answers ) )->get();
524  }
525 
526  public function aggregateAnswers($relevant_answers_chosen)
527  {
528  $aggregate = array();
529 
530  foreach ($relevant_answers_chosen as $relevant_answer)
531  {
532  if ( array_key_exists($relevant_answer['value1'], $aggregate) )
533  {
534  $aggregate[$relevant_answer['value1']]++;
535  }
536  else
537  {
538  $aggregate[$relevant_answer['value1']] = 1;
539  }
540  }
541  return $aggregate;
542  }
543 
549  public function renderAggregateView($aggregate)
550  {
551  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
552 
553  foreach ($aggregate as $key => $value)
554  {
555  $tpl->setCurrentBlock( 'aggregaterow' );
556  $tpl->setVariable( 'OPTION', $key );
557  $tpl->setVariable( 'COUNT', $value );
558  $tpl->parseCurrentBlock();
559  }
560  return $tpl;
561  }
562 }
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
This class represents a selection list property in a property form.
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
This class represents a property form user interface.
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
$_GET["client_id"]
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
getTestOutput($active_id, $pass=NULL, $is_postponed=FALSE, $use_post_solutions=FALSE, $inlineFeedback=false)
getSpecificFeedbackOutput($active_id, $pass)
Class for TextSubset questions.
addItem($a_item)
Add Item (Property, SectionHeader).
$url
Definition: shib_logout.php:72
getQuestionTemplate()
get question template
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
populateTaxonomyFormSection(ilPropertyFormGUI $form)
removeanswers()
Remove an answer.
This class represents a single choice wizard property in a property form.
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
setMinValue($a_minvalue, $a_display_always=false)
Set Minimum Value.
getILIASPage($html="")
Returns the ILIAS Page around a question.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
This class represents a number property in a property form.
special template class to simplify handling of ITX/PEAR
writePostData($always=false)
{}
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
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.
setOptions($a_options)
Set Options.
Basic GUI class for assessment questions.
Create styles array
The data for the language used.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
$errors
Create new PHPExcel object
obj_idprivate
Multiple choice question GUI representation.
addBackTab(ilTabsGUI $ilTabs)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
Interface ilGuiAnswerScoringAdjustable.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
Interface ilGuiQuestionScoringAdjustable.
__construct($id=-1)
assTextSubsetGUI constructor
setQuestionTabs()
Sets the ILIAS tabs for this question type.
aggregateAnswers($relevant_answers_chosen)
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
$_POST["username"]
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
setRequired($a_required)
Set Required.
addanswers()
Add a new answer.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.