ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 
26 {
36  public function __construct($id = -1)
37  {
38  parent::__construct();
39  require_once './Modules/TestQuestionPool/classes/class.assNumeric.php';
40  $this->object = new assNumeric();
41  if ($id >= 0)
42  {
43  $this->object->loadFromDb($id);
44  }
45  }
46 
47  function getCommand($cmd)
48  {
49  if (substr($cmd, 0, 6) == "delete")
50  {
51  $cmd = "delete";
52  }
53  return $cmd;
54  }
55 
59  protected function writePostData($always = false)
60  {
61  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
62  if (!$hasErrors)
63  {
64  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
68  $this->saveTaxonomyAssignments();
69  return 0;
70  }
71  return 1;
72  }
73 
81  public function editQuestion($checkonly = FALSE)
82  {
83  $save = $this->isSaveCommand();
84  $this->getQuestionTemplate();
85 
86  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
87  $form = new ilPropertyFormGUI();
88  $this->editForm = $form;
89 
90  $form->setFormAction($this->ctrl->getFormAction($this));
91  $form->setTitle($this->outQuestionType());
92  $form->setMultipart(TRUE);
93  $form->setTableWidth("100%");
94  $form->setId("assnumeric");
95 
96  $this->addBasicQuestionFormProperties( $form );
97  $this->populateQuestionSpecificFormPart( $form );
98  $this->populateAnswerSpecificFormPart( $form );
99  $this->populateTaxonomyFormSection($form);
100  $this->addQuestionFormCommandButtons($form);
101 
102  $errors = false;
103 
104  if ($save)
105  {
106  $form->setValuesByPost();
107  $errors = !$form->checkInput();
108  $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
109 
110  $lower = $form->getItemByPostVar('lowerlimit');
111  $upper = $form->getItemByPostVar('upperlimit');
112 
113  if( !$this->checkRange($lower->getValue(), $upper->getValue()) )
114  {
115  global $DIC;
116  $lower->setAlert($DIC->language()->txt('qpl_numeric_lower_needs_valid_lower_alert'));
117  $upper->setAlert($DIC->language()->txt('qpl_numeric_upper_needs_valid_upper_alert'));
118  ilUtil::sendFailure($DIC->language()->txt("form_input_not_valid"));
119  $errors = true;
120  }
121 
122  if ($errors) $checkonly = false;
123  }
124 
125  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
126  return $errors;
127  }
128 
136  public function checkRange($lower, $upper)
137  {
138  include_once "./Services/Math/classes/class.EvalMath.php";
139  $eval = new EvalMath();
140  $eval->suppress_errors = TRUE;
141  if (($eval->e($lower) !== FALSE) AND ($eval->e($upper) !== FALSE))
142  {
143  if ($eval->e($lower) <= $eval->e($upper))
144  {
145  return TRUE;
146  }
147  else
148  {
149  return FALSE;
150  }
151  }
152  return FALSE;
153  }
154 
171  $active_id,
172  $pass = NULL,
173  $graphicalOutput = FALSE,
174  $result_output = FALSE,
175  $show_question_only = TRUE,
176  $show_feedback = FALSE,
177  $show_correct_solution = FALSE,
178  $show_manual_scoring = FALSE,
179  $show_question_text = TRUE
180  )
181  {
182  // get the solution of the user for the active pass or from the last pass if allowed
183  $solutions = array();
184  if (($active_id > 0) && (!$show_correct_solution))
185  {
186  $solutions =& $this->object->getSolutionValues($active_id, $pass);
187  }
188  else
189  {
190  array_push($solutions, array("value1" => sprintf($this->lng->txt("value_between_x_and_y"), $this->object->getLowerLimit(), $this->object->getUpperLimit())));
191  }
192 
193  // generate the question output
194  require_once './Services/UICore/classes/class.ilTemplate.php';
195  $template = new ilTemplate("tpl.il_as_qpl_numeric_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
196  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
197  if (is_array($solutions))
198  {
199  if (($active_id > 0) && (!$show_correct_solution))
200  {
201  if ($graphicalOutput)
202  {
203  if($this->object->getStep() === NULL)
204  {
205  $reached_points = $this->object->getReachedPoints($active_id, $pass);
206  }
207  else
208  {
209  $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
210  }
211  // output of ok/not ok icons for user entered solutions
212  if ($reached_points == $this->object->getMaximumPoints())
213  {
214  $template->setCurrentBlock("icon_ok");
215  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
216  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
217  $template->parseCurrentBlock();
218  }
219  else
220  {
221  $template->setCurrentBlock("icon_ok");
222  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
223  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
224  $template->parseCurrentBlock();
225  }
226  }
227  }
228  foreach ($solutions as $solution)
229  {
230  $template->setVariable("NUMERIC_VALUE", $solution["value1"]);
231  }
232  if (count($solutions) == 0)
233  {
234  $template->setVariable("NUMERIC_VALUE", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
235  }
236  }
237  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
238  $questiontext = $this->object->getQuestion();
239  if ($show_question_text==true)
240  {
241  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
242  }
243  $questionoutput = $template->get();
244  //$feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : ""; // Moving new method
245  // due to deprecation.
246  $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput($active_id, $pass) : "";
247  if (strlen($feedback))
248  {
249  $cssClass = ( $this->hasCorrectSolution($active_id, $pass) ?
251  );
252 
253  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
254  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback, true ));
255  }
256  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
257 
258  $solutionoutput = $solutiontemplate->get();
259  if (!$show_question_only)
260  {
261  // get page object output
262  $solutionoutput = $this->getILIASPage($solutionoutput);
263  }
264  return $solutionoutput;
265  }
266 
272  public function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
273  {
274  // generate the question output
275  require_once './Services/UICore/classes/class.ilTemplate.php';
276  $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
277  if( is_object($this->getPreviewSession()) )
278  {
279  $template->setVariable("NUMERIC_VALUE", " value=\"".$this->getPreviewSession()->getParticipantsSolution()."\"");
280  }
281  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
282  $questiontext = $this->object->getQuestion();
283  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
284  $questionoutput = $template->get();
285  if (!$show_question_only)
286  {
287  // get page object output
288  $questionoutput = $this->getILIASPage($questionoutput);
289  }
290  return $questionoutput;
291  }
292 
301  // hey: prevPassSolutions - pass will be always available from now on
302  public function getTestOutput($active_id, $pass, $is_postponed = FALSE, $use_post_solutions = FALSE, $inlineFeedback)
303  // hey.
304  {
305  $solutions = NULL;
306  // get the solution of the user for the active pass or from the last pass if allowed
307  if($use_post_solutions !== false)
308  {
309  $solutions = array(
310  array('value1' => $use_post_solutions['numeric_result'])
311  );
312  }
313  elseif ($active_id)
314  {
315 
316  // hey: prevPassSolutions - obsolete due to central check
317  #include_once "./Modules/Test/classes/class.ilObjTest.php";
318  #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
319  #{
320  # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
321  #}
322  $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
323  // hey.
324  }
325 
326  // generate the question output
327  require_once './Services/UICore/classes/class.ilTemplate.php';
328  $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
329  if (is_array($solutions))
330  {
331  foreach ($solutions as $solution)
332  {
333  $template->setVariable("NUMERIC_VALUE", " value=\"".$solution["value1"]."\"");
334  }
335  }
336  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
337  $questiontext = $this->object->getQuestion();
338  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
339  $questionoutput = $template->get();
340  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
341  return $pageoutput;
342  }
343 
349  public function setQuestionTabs()
350  {
353  global $rbacsystem, $ilTabs;
354 
355  $ilTabs->clearTargets();
356 
357  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
358  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
359  $q_type = $this->object->getQuestionType();
360 
361  if (strlen($q_type))
362  {
363  $classname = $q_type . "GUI";
364  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
365  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
366  }
367 
368  if ($_GET["q_id"])
369  {
370  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
371  {
372  // edit page
373  $ilTabs->addTarget("edit_page",
374  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
375  array("edit", "insert", "exec_pg"),
376  "", "", $force_active);
377  }
378 
379  $this->addTab_QuestionPreview($ilTabs);
380  }
381 
382  $force_active = false;
383  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
384  {
385  $url = "";
386  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
387  // edit question properties
388  $ilTabs->addTarget("edit_question",
389  $url,
390  array("editQuestion", "save", "cancel", "saveEdit", "originalSyncForm"),
391  $classname, "", $force_active);
392  }
393 
394  // add tab for question feedback within common class assQuestionGUI
395  $this->addTab_QuestionFeedback($ilTabs);
396 
397  // add tab for question hint within common class assQuestionGUI
398  $this->addTab_QuestionHints($ilTabs);
399 
400  // add tab for question's suggested solution within common class assQuestionGUI
401  $this->addTab_SuggestedSolution($ilTabs, $classname);
402 
403  // Assessment of questions sub menu entry
404  if ($_GET["q_id"])
405  {
406  $ilTabs->addTarget("statistics",
407  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
408  array("assessment"),
409  $classname, "");
410  }
411 
412  $this->addBackTab($ilTabs);
413  }
414 
421  public function getSpecificFeedbackOutput($active_id, $pass)
422  {
423  $output = "";
424  return $this->object->prepareTextareaOutput($output, TRUE);
425  }
426 
428  {
429  $this->object->setMaxChars( $_POST["maxchars"] );
430  }
431 
433  {
434  $this->object->setLowerLimit( $_POST['lowerlimit'] );
435  $this->object->setUpperLimit( $_POST['upperlimit'] );
436  $this->object->setPoints( $_POST['points'] );
437  }
438 
440  {
441  // maxchars
442  $maxchars = new ilNumberInputGUI($this->lng->txt( "maxchars" ), "maxchars");
443  $maxchars->setInfo($this->lng->txt('qpl_maxchars_info_numeric_question'));
444  $maxchars->setSize( 10 );
445  $maxchars->setDecimals( 0 );
446  $maxchars->setMinValue( 1 );
447  $maxchars->setRequired( true );
448  if ($this->object->getMaxChars() > 0)
449  {
450  $maxchars->setValue($this->object->getMaxChars());
451  }
452  $form->addItem( $maxchars );
453  }
454 
456  {
457  // points
458  $points = new ilNumberInputGUI($this->lng->txt( "points" ), "points");
459  $points->allowDecimals(true);
460  $points->setValue( $this->object->getPoints() > 0 ? $this->object->getPoints() : '' );
461  $points->setRequired( TRUE );
462  $points->setSize( 3 );
463  $points->setMinValue( 0.0 );
464  $points->setMinvalueShouldBeGreater( true );
465  $form->addItem( $points );
466 
468  $header->setTitle( $this->lng->txt( "range" ) );
469  $form->addItem( $header );
470 
471  // lower bound
472  $lower_limit = new ilFormulaInputGUI($this->lng->txt( "range_lower_limit" ), "lowerlimit");
473  $lower_limit->setSize( 25 );
474  $lower_limit->setMaxLength( 20 );
475  $lower_limit->setRequired( true );
476  $lower_limit->setValue( $this->object->getLowerLimit() );
477  $form->addItem( $lower_limit );
478 
479  // upper bound
480  $upper_limit = new ilFormulaInputGUI($this->lng->txt( "range_upper_limit" ), "upperlimit");
481  $upper_limit->setSize( 25 );
482  $upper_limit->setMaxLength( 20 );
483  $upper_limit->setRequired( true );
484  $upper_limit->setValue( $this->object->getUpperLimit() );
485  $form->addItem( $upper_limit );
486 
487  // reset input length, if max chars are set
488  if( $this->object->getMaxChars() > 0 )
489  {
490  $lower_limit->setSize( $this->object->getMaxChars() );
491  $lower_limit->setMaxLength( $this->object->getMaxChars() );
492  $upper_limit->setSize( $this->object->getMaxChars() );
493  $upper_limit->setMaxLength( $this->object->getMaxChars() );
494  }
495  }
496 
507  {
508  return array();
509  }
510 
521  {
522  return array();
523  }
524 
533  public function getAggregatedAnswersView($relevant_answers)
534  {
535  return $this->renderAggregateView(
536  $this->aggregateAnswers( $relevant_answers ) )->get();
537  }
538 
539  public function aggregateAnswers($relevant_answers_chosen)
540  {
541  $aggregate = array();
542 
543  foreach ($relevant_answers_chosen as $relevant_answer)
544  {
545  if ( array_key_exists($relevant_answer['value1'], $aggregate) )
546  {
547  $aggregate[$relevant_answer['value1']]++;
548  }
549  else
550  {
551  $aggregate[$relevant_answer['value1']] = 1;
552  }
553  }
554  return $aggregate;
555  }
556 
562  public function renderAggregateView($aggregate)
563  {
564  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
565 
566  $tpl->setCurrentBlock('headercell');
567  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
568  $tpl->parseCurrentBlock();
569 
570  $tpl->setCurrentBlock('headercell');
571  $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
572  $tpl->parseCurrentBlock();
573 
574  foreach ($aggregate as $key => $value)
575  {
576  $tpl->setCurrentBlock( 'aggregaterow' );
577  $tpl->setVariable( 'OPTION', $key );
578  $tpl->setVariable( 'COUNT', $value );
579  $tpl->parseCurrentBlock();
580  }
581  return $tpl;
582  }
583 }
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.
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
addItem($a_item)
Add Item (Property, SectionHeader).
$url
Definition: shib_logout.php:72
writePostData($always=false)
{}
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.
checkRange($lower, $upper)
Checks the range limits.
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
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.
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)
Create styles array
The data for the language used.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
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.
Create new PHPExcel object
obj_idprivate
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
global $DIC
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.
$_POST["username"]
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.