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
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
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';
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 );
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}
sprintf('%.4f', $callTime)
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Numeric question GUI representation.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
checkRange($lower, $upper)
Checks the range limits.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
getSpecificFeedbackOutput($active_id, $pass)
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
__construct($id=-1)
assNumericGUI constructor
aggregateAnswers($relevant_answers_chosen)
getTestOutput($active_id, $pass, $is_postponed=FALSE, $use_post_solutions=FALSE, $inlineFeedback)
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getAfterParticipationSuppressionAnswerPostVars()
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.
renderAggregateView($aggregate)
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
Class for numeric questions.
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
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
addBackTab(ilTabsGUI $ilTabs)
hasCorrectSolution($activeId, $passIndex)
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)
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
This class represents a section header in a property form.
This class represents a formula text property in a property form.
This class represents a number property in a property form.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
special template class to simplify handling of ITX/PEAR
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
$header
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$cmd
Definition: sahs_server.php:35
$url
Definition: shib_logout.php:72
$errors
global $DIC