ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5
class.assNumericGUI.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 {
35  public function __construct($id = -1)
36  {
37  parent::__construct();
38  require_once './Modules/TestQuestionPool/classes/class.assNumeric.php';
39  $this->object = new assNumeric();
40  if ($id >= 0)
41  {
42  $this->object->loadFromDb($id);
43  }
44  }
45 
46  function getCommand($cmd)
47  {
48  if (substr($cmd, 0, 6) == "delete")
49  {
50  $cmd = "delete";
51  }
52  return $cmd;
53  }
54 
62  public function writePostData($always = false)
63  {
64  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
65  if (!$hasErrors)
66  {
67  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
71  $this->saveTaxonomyAssignments();
72  return 0;
73  }
74  return 1;
75  }
76 
84  public function editQuestion($checkonly = FALSE)
85  {
86  $save = $this->isSaveCommand();
87  $this->getQuestionTemplate();
88 
89  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
90  $form = new ilPropertyFormGUI();
91  $form->setFormAction($this->ctrl->getFormAction($this));
92  $form->setTitle($this->outQuestionType());
93  $form->setMultipart(TRUE);
94  $form->setTableWidth("100%");
95  $form->setId("assnumeric");
96 
97  $this->addBasicQuestionFormProperties( $form );
98  $this->populateQuestionSpecificFormPart( $form );
99  $this->populateAnswerSpecificFormPart( $form );
100  $this->populateTaxonomyFormSection($form);
101  $this->addQuestionFormCommandButtons($form);
102 
103  $errors = false;
104 
105  if ($save)
106  {
107  $form->setValuesByPost();
108  $errors = !$form->checkInput();
109  $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
110  if ($errors) $checkonly = false;
111  }
112 
113  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
114  return $errors;
115  }
116 
124  public function checkRange()
125  {
126  include_once "./Services/Math/classes/class.EvalMath.php";
127  $eval = new EvalMath();
128  $eval->suppress_errors = TRUE;
129  if (($eval->e($_POST["rang_lower_limit"]) !== FALSE) AND ($eval->e($_POST ["range_upper_limit"]) !== FALSE))
130  {
131  if ($eval->e($_POST["rang_lower_limit"]) < $eval->e($_POST["range_upper_limit"]))
132  {
133  return TRUE;
134  }
135  else
136  {
137  return FALSE;
138  }
139  }
140  return FALSE;
141  }
142 
159  $active_id,
160  $pass = NULL,
161  $graphicalOutput = FALSE,
162  $result_output = FALSE,
163  $show_question_only = TRUE,
164  $show_feedback = FALSE,
165  $show_correct_solution = FALSE,
166  $show_manual_scoring = FALSE,
167  $show_question_text = TRUE
168  )
169  {
170  // get the solution of the user for the active pass or from the last pass if allowed
171  $solutions = array();
172  if (($active_id > 0) && (!$show_correct_solution))
173  {
174  $solutions =& $this->object->getSolutionValues($active_id, $pass);
175  }
176  else
177  {
178  array_push($solutions, array("value1" => sprintf($this->lng->txt("value_between_x_and_y"), $this->object->getLowerLimit(), $this->object->getUpperLimit())));
179  }
180 
181  // generate the question output
182  require_once './Services/UICore/classes/class.ilTemplate.php';
183  $template = new ilTemplate("tpl.il_as_qpl_numeric_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
184  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
185  if (is_array($solutions))
186  {
187  if (($active_id > 0) && (!$show_correct_solution))
188  {
189  if ($graphicalOutput)
190  {
191  if($this->object->getStep() === NULL)
192  {
193  $reached_points = $this->object->getReachedPoints($active_id, $pass);
194  }
195  else
196  {
197  $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
198  }
199  // output of ok/not ok icons for user entered solutions
200  if ($reached_points == $this->object->getMaximumPoints())
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  foreach ($solutions as $solution)
217  {
218  $template->setVariable("NUMERIC_VALUE", $solution["value1"]);
219  }
220  if (count($solutions) == 0)
221  {
222  $template->setVariable("NUMERIC_VALUE", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
223  }
224  }
225  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
226  $questiontext = $this->object->getQuestion();
227  if ($show_question_text==true)
228  {
229  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
230  }
231  $questionoutput = $template->get();
232  //$feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : ""; // Moving new method
233  // due to deprecation.
234  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput($active_id, $pass) : "";
235  if (strlen($feedback))
236  {
237  $cssClass = ( $this->hasCorrectSolution($active_id, $pass) ?
239  );
240 
241  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
242  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
243  }
244  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
245 
246  $solutionoutput = $solutiontemplate->get();
247  if (!$show_question_only)
248  {
249  // get page object output
250  $solutionoutput = $this->getILIASPage($solutionoutput);
251  }
252  return $solutionoutput;
253  }
254 
260  public function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
261  {
262  // generate the question output
263  require_once './Services/UICore/classes/class.ilTemplate.php';
264  $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
265  if( is_object($this->getPreviewSession()) )
266  {
267  $template->setVariable("NUMERIC_VALUE", " value=\"".$this->getPreviewSession()->getParticipantsSolution()."\"");
268  }
269  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
270  $questiontext = $this->object->getQuestion();
271  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
272  $questionoutput = $template->get();
273  if (!$show_question_only)
274  {
275  // get page object output
276  $questionoutput = $this->getILIASPage($questionoutput);
277  }
278  return $questionoutput;
279  }
280 
289  // hey: prevPassSolutions - pass will be always available from now on
290  public function getTestOutput($active_id, $pass, $is_postponed = FALSE, $use_post_solutions = FALSE, $inlineFeedback)
291  // hey.
292  {
293  $solutions = NULL;
294  // get the solution of the user for the active pass or from the last pass if allowed
295  if ($active_id)
296  {
297 
298  // hey: prevPassSolutions - obsolete due to central check
299  #include_once "./Modules/Test/classes/class.ilObjTest.php";
300  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
301  #{
302  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
303  #}
304  $solutions = $this->getTestOutputSolutions($active_id, $pass);
305  // hey.
306  }
307 
308  // generate the question output
309  require_once './Services/UICore/classes/class.ilTemplate.php';
310  $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
311  if (is_array($solutions))
312  {
313  foreach ($solutions as $solution)
314  {
315  $template->setVariable("NUMERIC_VALUE", " value=\"".$solution["value1"]."\"");
316  }
317  }
318  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
319  $questiontext = $this->object->getQuestion();
320  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
321  $questionoutput = $template->get();
322  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
323  return $pageoutput;
324  }
325 
331  public function setQuestionTabs()
332  {
335  global $rbacsystem, $ilTabs;
336 
337  $ilTabs->clearTargets();
338 
339  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
340  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
341  $q_type = $this->object->getQuestionType();
342 
343  if (strlen($q_type))
344  {
345  $classname = $q_type . "GUI";
346  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
347  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
348  }
349 
350  if ($_GET["q_id"])
351  {
352  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
353  {
354  // edit page
355  $ilTabs->addTarget("edit_page",
356  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
357  array("edit", "insert", "exec_pg"),
358  "", "", $force_active);
359  }
360 
361  $this->addTab_QuestionPreview($ilTabs);
362  }
363 
364  $force_active = false;
365  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
366  {
367  $url = "";
368  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
369  // edit question properties
370  $ilTabs->addTarget("edit_question",
371  $url,
372  array("editQuestion", "save", "cancel", "saveEdit", "originalSyncForm"),
373  $classname, "", $force_active);
374  }
375 
376  // add tab for question feedback within common class assQuestionGUI
377  $this->addTab_QuestionFeedback($ilTabs);
378 
379  // add tab for question hint within common class assQuestionGUI
380  $this->addTab_QuestionHints($ilTabs);
381 
382  // add tab for question's suggested solution within common class assQuestionGUI
383  $this->addTab_SuggestedSolution($ilTabs, $classname);
384 
385  // Assessment of questions sub menu entry
386  if ($_GET["q_id"])
387  {
388  $ilTabs->addTarget("statistics",
389  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
390  array("assessment"),
391  $classname, "");
392  }
393 
394  $this->addBackTab($ilTabs);
395  }
396 
403  public function getSpecificFeedbackOutput($active_id, $pass)
404  {
405  $output = "";
406  return $this->object->prepareTextareaOutput($output, TRUE);
407  }
408 
410  {
411  $this->object->setMaxChars( $_POST["maxchars"] );
412  }
413 
415  {
416  $this->object->setLowerLimit( $_POST['lowerlimit'] );
417  $this->object->setUpperLimit( $_POST['upperlimit'] );
418  $this->object->setPoints( $_POST['points'] );
419  }
420 
422  {
423  // maxchars
424  $maxchars = new ilNumberInputGUI($this->lng->txt( "maxchars" ), "maxchars");
425  $maxchars->setInfo($this->lng->txt('qpl_maxchars_info_numeric_question'));
426  $maxchars->setSize( 10 );
427  $maxchars->setDecimals( 0 );
428  $maxchars->setMinValue( 1 );
429  $maxchars->setRequired( true );
430  if ($this->object->getMaxChars() > 0)
431  {
432  $maxchars->setValue($this->object->getMaxChars());
433  }
434  $form->addItem( $maxchars );
435  }
436 
438  {
439  // points
440  $points = new ilNumberInputGUI($this->lng->txt( "points" ), "points");
441  $points->allowDecimals(true);
442  $points->setValue( $this->object->getPoints() > 0 ? $this->object->getPoints() : '' );
443  $points->setRequired( TRUE );
444  $points->setSize( 3 );
445  $points->setMinValue( 0.0 );
446  $points->setMinvalueShouldBeGreater( true );
447  $form->addItem( $points );
448 
450  $header->setTitle( $this->lng->txt( "range" ) );
451  $form->addItem( $header );
452 
453  // lower bound
454  $lower_limit = new ilFormulaInputGUI($this->lng->txt( "range_lower_limit" ), "lowerlimit");
455  $lower_limit->setSize( 25 );
456  $lower_limit->setMaxLength( 20 );
457  $lower_limit->setRequired( true );
458  $lower_limit->setValue( $this->object->getLowerLimit() );
459  $form->addItem( $lower_limit );
460 
461  // upper bound
462  $upper_limit = new ilFormulaInputGUI($this->lng->txt( "range_upper_limit" ), "upperlimit");
463  $upper_limit->setSize( 25 );
464  $upper_limit->setMaxLength( 20 );
465  $upper_limit->setRequired( true );
466  $upper_limit->setValue( $this->object->getUpperLimit() );
467  $form->addItem( $upper_limit );
468 
469  // reset input length, if max chars are set
470  if( $this->object->getMaxChars() > 0 )
471  {
472  $lower_limit->setSize( $this->object->getMaxChars() );
473  $lower_limit->setMaxLength( $this->object->getMaxChars() );
474  $upper_limit->setSize( $this->object->getMaxChars() );
475  $upper_limit->setMaxLength( $this->object->getMaxChars() );
476  }
477  }
478 
489  {
490  return array();
491  }
492 
503  {
504  return array();
505  }
506 
515  public function getAggregatedAnswersView($relevant_answers)
516  {
517  return $this->renderAggregateView(
518  $this->aggregateAnswers( $relevant_answers ) )->get();
519  }
520 
521  public function aggregateAnswers($relevant_answers_chosen)
522  {
523  $aggregate = array();
524 
525  foreach ($relevant_answers_chosen as $relevant_answer)
526  {
527  if ( array_key_exists($relevant_answer['value1'], $aggregate) )
528  {
529  $aggregate[$relevant_answer['value1']]++;
530  }
531  else
532  {
533  $aggregate[$relevant_answer['value1']] = 1;
534  }
535  }
536  return $aggregate;
537  }
538 
544  public function renderAggregateView($aggregate)
545  {
546  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
547 
548  $tpl->setCurrentBlock('headercell');
549  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
550  $tpl->parseCurrentBlock();
551 
552  $tpl->setCurrentBlock('headercell');
553  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
554  $tpl->parseCurrentBlock();
555 
556  foreach ($aggregate as $key => $value)
557  {
558  $tpl->setCurrentBlock( 'aggregaterow' );
559  $tpl->setVariable( 'OPTION', $key );
560  $tpl->setVariable( 'COUNT', $value );
561  $tpl->parseCurrentBlock();
562  }
563  return $tpl;
564  }
565 }
This class represents a formula text property in a property form.
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
$_POST['username']
Definition: cron.php:12
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...
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
$_GET["client_id"]
This class represents a section header in a property form.
aggregateAnswers($relevant_answers_chosen)
getSpecificFeedbackOutput($active_id, $pass)
$cmd
Definition: sahs_server.php:35
getTestOutputSolutions($activeId, $pass)
addItem($a_item)
Add Item (Property, SectionHeader).
$url
Definition: shib_logout.php:72
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
getQuestionTemplate()
get question template
populateTaxonomyFormSection(ilPropertyFormGUI $form)
allowDecimals($a_value)
Toggle Decimals.
setInfo($a_info)
Set Information Text.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
Numeric question GUI representation.
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.
$header
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.
checkRange()
Checks the range limits.
special template class to simplify handling of ITX/PEAR
setSize($a_size)
Set Size.
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
Basic GUI class for assessment questions.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getTestOutput($active_id, $pass, $is_postponed=FALSE, $use_post_solutions=FALSE, $inlineFeedback)
$errors
Class for numeric questions.
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
addBackTab(ilTabsGUI $ilTabs)
__construct($id=-1)
assNumericGUI constructor
Interface ilGuiAnswerScoringAdjustable.
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
renderAggregateView($aggregate)
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
Interface ilGuiQuestionScoringAdjustable.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.