ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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  {
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->getGenericFeedbackOutput($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 
252  public function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
253  {
254  // generate the question output
255  require_once './Services/UICore/classes/class.ilTemplate.php';
256  $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
257  if( is_object($this->getPreviewSession()) )
258  {
259  $template->setVariable("NUMERIC_VALUE", " value=\"".$this->getPreviewSession()->getParticipantsSolution()."\"");
260  }
261  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
262  $questiontext = $this->object->getQuestion();
263  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
264  $questionoutput = $template->get();
265  if (!$show_question_only)
266  {
267  // get page object output
268  $questionoutput = $this->getILIASPage($questionoutput);
269  }
270  return $questionoutput;
271  }
272 
281  public function getTestOutput($active_id, $pass = NULL, $is_postponed = FALSE, $use_post_solutions = FALSE)
282  {
283  $solutions = NULL;
284  // get the solution of the user for the active pass or from the last pass if allowed
285  if ($active_id)
286  {
287 
288  require_once './Modules/Test/classes/class.ilObjTest.php';
289  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
290  {
291  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
292  }
293  $solutions =& $this->object->getSolutionValues($active_id, $pass);
294  }
295 
296  // generate the question output
297  require_once './Services/UICore/classes/class.ilTemplate.php';
298  $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
299  if (is_array($solutions))
300  {
301  foreach ($solutions as $solution)
302  {
303  $template->setVariable("NUMERIC_VALUE", " value=\"".$solution["value1"]."\"");
304  }
305  }
306  $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
307  $questiontext = $this->object->getQuestion();
308  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
309  $questionoutput = $template->get();
310  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
311  return $pageoutput;
312  }
313 
319  public function setQuestionTabs()
320  {
323  global $rbacsystem, $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  {
333  $classname = $q_type . "GUI";
334  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
335  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
336  }
337 
338  if ($_GET["q_id"])
339  {
340  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
341  {
342  // edit page
343  $ilTabs->addTarget("edit_page",
344  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
345  array("edit", "insert", "exec_pg"),
346  "", "", $force_active);
347  }
348 
349  $this->addTab_QuestionPreview($ilTabs);
350  }
351 
352  $force_active = false;
353  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
354  {
355  $url = "";
356  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
357  // edit question properties
358  $ilTabs->addTarget("edit_question",
359  $url,
360  array("editQuestion", "save", "cancel", "saveEdit", "originalSyncForm"),
361  $classname, "", $force_active);
362  }
363 
364  // add tab for question feedback within common class assQuestionGUI
365  $this->addTab_QuestionFeedback($ilTabs);
366 
367  // add tab for question hint within common class assQuestionGUI
368  $this->addTab_QuestionHints($ilTabs);
369 
370  // add tab for question's suggested solution within common class assQuestionGUI
371  $this->addTab_SuggestedSolution($ilTabs, $classname);
372 
373  // Assessment of questions sub menu entry
374  if ($_GET["q_id"])
375  {
376  $ilTabs->addTarget("statistics",
377  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
378  array("assessment"),
379  $classname, "");
380  }
381 
382  $this->addBackTab($ilTabs);
383  }
384 
391  public function getSpecificFeedbackOutput($active_id, $pass)
392  {
393  $output = "";
394  return $this->object->prepareTextareaOutput($output, TRUE);
395  }
396 
398  {
399  $this->object->setMaxChars( $_POST["maxchars"] );
400  }
401 
403  {
404  $this->object->setLowerLimit( $_POST['lowerlimit'] );
405  $this->object->setUpperLimit( $_POST['upperlimit'] );
406  $this->object->setPoints( $_POST['points'] );
407  }
408 
410  {
411  // maxchars
412  $maxchars = new ilNumberInputGUI($this->lng->txt( "maxchars" ), "maxchars");
413  $maxchars->setInfo($this->lng->txt('qpl_maxchars_info_numeric_question'));
414  $maxchars->setSize( 10 );
415  $maxchars->setDecimals( 0 );
416  $maxchars->setMinValue( 1 );
417  $maxchars->setRequired( true );
418  if ($this->object->getMaxChars() > 0)
419  {
420  $maxchars->setValue($this->object->getMaxChars());
421  }
422  $form->addItem( $maxchars );
423  }
424 
426  {
427  // points
428  $points = new ilNumberInputGUI($this->lng->txt( "points" ), "points");
429  $points->allowDecimals(true);
430  $points->setValue( $this->object->getPoints() > 0 ? $this->object->getPoints() : '' );
431  $points->setRequired( TRUE );
432  $points->setSize( 3 );
433  $points->setMinValue( 0.0 );
434  $points->setMinvalueShouldBeGreater( true );
435  $form->addItem( $points );
436 
437  $header = new ilFormSectionHeaderGUI();
438  $header->setTitle( $this->lng->txt( "range" ) );
439  $form->addItem( $header );
440 
441  // lower bound
442  $lower_limit = new ilFormulaInputGUI($this->lng->txt( "range_lower_limit" ), "lowerlimit");
443  $lower_limit->setSize( 25 );
444  $lower_limit->setMaxLength( 20 );
445  $lower_limit->setRequired( true );
446  $lower_limit->setValue( $this->object->getLowerLimit() );
447  $form->addItem( $lower_limit );
448 
449  // upper bound
450  $upper_limit = new ilFormulaInputGUI($this->lng->txt( "range_upper_limit" ), "upperlimit");
451  $upper_limit->setSize( 25 );
452  $upper_limit->setMaxLength( 20 );
453  $upper_limit->setRequired( true );
454  $upper_limit->setValue( $this->object->getUpperLimit() );
455  $form->addItem( $upper_limit );
456 
457  // reset input length, if max chars are set
458  if( $this->object->getMaxChars() > 0 )
459  {
460  $lower_limit->setSize( $this->object->getMaxChars() );
461  $lower_limit->setMaxLength( $this->object->getMaxChars() );
462  $upper_limit->setSize( $this->object->getMaxChars() );
463  $upper_limit->setMaxLength( $this->object->getMaxChars() );
464  }
465  }
466 
477  {
478  return array();
479  }
480 
491  {
492  return array();
493  }
494 
503  public function getAggregatedAnswersView($relevant_answers)
504  {
505  return $this->renderAggregateView(
506  $this->aggregateAnswers( $relevant_answers ) )->get();
507  }
508 
509  public function aggregateAnswers($relevant_answers_chosen)
510  {
511  $aggregate = array();
512 
513  foreach ($relevant_answers_chosen as $relevant_answer)
514  {
515  if ( array_key_exists($relevant_answer['value1'], $aggregate) )
516  {
517  $aggregate[$relevant_answer['value1']]++;
518  }
519  else
520  {
521  $aggregate[$relevant_answer['value1']] = 1;
522  }
523  }
524  return $aggregate;
525  }
526 
532  public function renderAggregateView($aggregate)
533  {
534  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
535 
536  foreach ($aggregate as $key => $value)
537  {
538  $tpl->setCurrentBlock( 'aggregaterow' );
539  $tpl->setVariable( 'OPTION', $key );
540  $tpl->setVariable( 'COUNT', $value );
541  $tpl->parseCurrentBlock();
542  }
543  return $tpl;
544  }
545 }