ILIAS  release_8 Revision v8.25-1-g13de6a5eca6
class.assNumericGUI.php
Go to the documentation of this file.
1<?php
18require_once './Modules/Test/classes/inc.AssessmentConstants.php';
19
37{
45 public function __construct($id = -1)
46 {
48 require_once './Modules/TestQuestionPool/classes/class.assNumeric.php';
49 $this->object = new assNumeric();
50 if ($id >= 0) {
51 $this->object->loadFromDb($id);
52 }
53 }
54
55 public function getCommand($cmd)
56 {
57 if (substr($cmd, 0, 6) == "delete") {
58 $cmd = "delete";
59 }
60 return $cmd;
61 }
62
66 protected function writePostData(bool $always = false): int
67 {
68 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
69 if (!$hasErrors) {
70 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
75 return 0;
76 }
77 return 1;
78 }
79
87 public function editQuestion($checkonly = false): bool
88 {
89 $save = $this->isSaveCommand();
90 $this->getQuestionTemplate();
91
92 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
93 $form = new ilPropertyFormGUI();
94 $this->editForm = $form;
95
96 $form->setFormAction($this->ctrl->getFormAction($this));
97 $form->setTitle($this->outQuestionType());
98 $form->setMultipart(true);
99 $form->setTableWidth("100%");
100 $form->setId("assnumeric");
101
102 $this->addBasicQuestionFormProperties($form);
104 $this->populateAnswerSpecificFormPart($form);
105 $this->populateTaxonomyFormSection($form);
106 $this->addQuestionFormCommandButtons($form);
107
108 $errors = false;
109
110 if ($save) {
111 $form->setValuesByPost();
112 $errors = !$form->checkInput();
113 $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
114
115 $lower = $form->getItemByPostVar('lowerlimit');
116 $upper = $form->getItemByPostVar('upperlimit');
117
118 if (!$this->checkRange($lower->getValue(), $upper->getValue())) {
119 global $DIC;
120 $lower->setAlert($DIC->language()->txt('qpl_numeric_lower_needs_valid_lower_alert'));
121 $upper->setAlert($DIC->language()->txt('qpl_numeric_upper_needs_valid_upper_alert'));
122 $this->tpl->setOnScreenMessage('failure', $DIC->language()->txt("form_input_not_valid"));
123 $errors = true;
124 }
125
126 if ($errors) {
127 $checkonly = false;
128 }
129 }
130
131 if (!$checkonly) {
132 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
133 }
134 return $errors;
135 }
136
144 public function checkRange($lower, $upper): bool
145 {
146 include_once "./Services/Math/classes/class.EvalMath.php";
147 $eval = new EvalMath();
148 $eval->suppress_errors = true;
149 if (($eval->e($lower) !== false) and ($eval->e($upper) !== false)) {
150 if ($eval->e($lower) <= $eval->e($upper)) {
151 return true;
152 } else {
153 return false;
154 }
155 }
156 return false;
157 }
158
172 public function getSolutionOutput(
173 $active_id,
174 $pass = null,
175 $graphicalOutput = false,
176 $result_output = false,
177 $show_question_only = true,
178 $show_feedback = false,
179 $show_correct_solution = false,
180 $show_manual_scoring = false,
181 $show_question_text = true
182 ): string {
183 // get the solution of the user for the active pass or from the last pass if allowed
184 $solutions = array();
185 if (($active_id > 0) && (!$show_correct_solution)) {
186 $solutions = $this->object->getSolutionValues($active_id, $pass);
187 } else {
188 array_push($solutions, array("value1" => sprintf($this->lng->txt("value_between_x_and_y"), $this->object->getLowerLimit(), $this->object->getUpperLimit())));
189 }
190
191 // generate the question output
192 require_once './Services/UICore/classes/class.ilTemplate.php';
193 $template = new ilTemplate("tpl.il_as_qpl_numeric_output_solution.html", true, true, "Modules/TestQuestionPool");
194 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
195 if (is_array($solutions)) {
196 if (($active_id > 0) && (!$show_correct_solution)) {
197 if ($graphicalOutput) {
198 if ($this->object->getStep() === null) {
199 $reached_points = $this->object->getReachedPoints($active_id, $pass);
200 } else {
201 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
202 }
203
204 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
205 if ($reached_points == $this->object->getMaximumPoints()) {
206 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
207 }
208 $template->setCurrentBlock("icon_ok");
209 $template->setVariable("ICON_OK", $correctness_icon);
210 $template->parseCurrentBlock();
211 }
212 }
213 foreach ($solutions as $solution) {
214 $template->setVariable("NUMERIC_VALUE", $solution["value1"]);
215 }
216 if (count($solutions) == 0) {
217 $template->setVariable("NUMERIC_VALUE", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
218 }
219 }
220 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
221 if ($show_question_text == true) {
222 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
223 }
224 $questionoutput = $template->get();
225 //$feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : ""; // Moving new method
226 // due to deprecation.
227 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput((int) $active_id, $pass) : "";
228 if (strlen($feedback)) {
229 $cssClass = (
230 $this->hasCorrectSolution($active_id, $pass) ?
232 );
233
234 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
235 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
236 }
237 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
238
239 $solutionoutput = $solutiontemplate->get();
240 if (!$show_question_only) {
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): string
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 $template->setVariable("NUMERIC_VALUE", " value=\"" . $this->getPreviewSession()->getParticipantsSolution() . "\"");
259 }
260 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
261 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
262 $questionoutput = $template->get();
263 if (!$show_question_only) {
264 // get page object output
265 $questionoutput = $this->getILIASPage($questionoutput);
266 }
267 return $questionoutput;
268 }
269
278 // hey: prevPassSolutions - pass will be always available from now on
279 public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $inlineFeedback = false): string
280 // hey.
281 {
282 $solutions = null;
283 // get the solution of the user for the active pass or from the last pass if allowed
284 if ($use_post_solutions !== false) {
286 $solutions = array(
287 array('value1' => $use_post_solutions['numeric_result'])
288 );
289 } elseif ($active_id) {
290 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
291 }
292
293 // generate the question output
294 require_once './Services/UICore/classes/class.ilTemplate.php';
295 $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", true, true, "Modules/TestQuestionPool");
296 if (is_array($solutions)) {
297 foreach ($solutions as $solution) {
298 $template->setVariable("NUMERIC_VALUE", " value=\"" . $solution["value1"] . "\"");
299 }
300 }
301 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
302 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
303 $questionoutput = $template->get();
304 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
305 return $pageoutput;
306 }
307
313 public function getSpecificFeedbackOutput(array $userSolution): string
314 {
315 $output = "";
316 return $this->object->prepareTextareaOutput($output, true);
317 }
318
320 {
321 $this->object->setMaxChars($_POST["maxchars"]);
322 }
323
325 {
326 $this->object->setLowerLimit($_POST['lowerlimit']);
327 $this->object->setUpperLimit($_POST['upperlimit']);
328 $this->object->setPoints((float) str_replace(',', '.', $_POST['points']));
329 }
330
332 {
333 // maxchars
334 $maxchars = new ilNumberInputGUI($this->lng->txt("maxchars"), "maxchars");
335 $maxchars->setInfo($this->lng->txt('qpl_maxchars_info_numeric_question'));
336 $maxchars->setSize(10);
337 $maxchars->setDecimals(0);
338 $maxchars->setMinValue(1);
339 $maxchars->setRequired(true);
340 if ($this->object->getMaxChars() > 0) {
341 $maxchars->setValue($this->object->getMaxChars());
342 }
343 $form->addItem($maxchars);
344 return $form;
345 }
346
348 {
349 // points
350 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
351 $points->allowDecimals(true);
352 $points->setValue($this->object->getPoints() > 0 ? $this->object->getPoints() : '');
353 $points->setRequired(true);
354 $points->setSize(3);
355 $points->setMinValue(0.0);
356 $points->setMinvalueShouldBeGreater(true);
357 $form->addItem($points);
358
359 $header = new ilFormSectionHeaderGUI();
360 $header->setTitle($this->lng->txt("range"));
361 $form->addItem($header);
362
363 // lower bound
364 $lower_limit = new ilFormulaInputGUI($this->lng->txt("range_lower_limit"), "lowerlimit");
365 $lower_limit->setSize(25);
366 $lower_limit->setMaxLength(20);
367 $lower_limit->setRequired(true);
368 $lower_limit->setValue((string) $this->object->getLowerLimit());
369 $form->addItem($lower_limit);
370
371 // upper bound
372 $upper_limit = new ilFormulaInputGUI($this->lng->txt("range_upper_limit"), "upperlimit");
373 $upper_limit->setSize(25);
374 $upper_limit->setMaxLength(20);
375 $upper_limit->setRequired(true);
376 $upper_limit->setValue((string) $this->object->getUpperLimit());
377 $form->addItem($upper_limit);
378
379 // reset input length, if max chars are set
380 if ($this->object->getMaxChars() > 0) {
381 $lower_limit->setSize($this->object->getMaxChars());
382 $lower_limit->setMaxLength($this->object->getMaxChars());
383 $upper_limit->setSize($this->object->getMaxChars());
384 $upper_limit->setMaxLength($this->object->getMaxChars());
385 }
386 return $form;
387 }
388
399 {
400 return array();
401 }
402
413 {
414 return array();
415 }
416
423 public function getAggregatedAnswersView(array $relevant_answers): string
424 {
425 return $this->renderAggregateView(
426 $this->aggregateAnswers($relevant_answers)
427 )->get();
428 }
429
430 public function aggregateAnswers($relevant_answers_chosen): array
431 {
432 $aggregate = array();
433
434 foreach ($relevant_answers_chosen as $relevant_answer) {
435 if (array_key_exists($relevant_answer['value1'], $aggregate)) {
436 $aggregate[$relevant_answer['value1']]++;
437 } else {
438 $aggregate[$relevant_answer['value1']] = 1;
439 }
440 }
441 return $aggregate;
442 }
443
449 public function renderAggregateView($aggregate): ilTemplate
450 {
451 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
452
453 $tpl->setCurrentBlock('headercell');
454 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
455 $tpl->parseCurrentBlock();
456
457 $tpl->setCurrentBlock('headercell');
458 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
459 $tpl->parseCurrentBlock();
460
461 foreach ($aggregate as $key => $value) {
462 $tpl->setCurrentBlock('aggregaterow');
463 $tpl->setVariable('OPTION', $key);
464 $tpl->setVariable('COUNT', $value);
465 $tpl->parseCurrentBlock();
466 }
467 return $tpl;
468 }
469
470 public function getAnswersFrequency($relevantAnswers, $questionIndex): array
471 {
472 $answers = array();
473
474 foreach ($relevantAnswers as $ans) {
475 if (!isset($answers[$ans['value1']])) {
476 $answers[$ans['value1']] = array(
477 'answer' => $ans['value1'], 'frequency' => 0
478 );
479 }
480
481 $answers[$ans['value1']]['frequency']++;
482 }
483
484 return $answers;
485 }
486
488 {
489 // points
490 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
491 $points->allowDecimals(true);
492 $points->setValue($this->object->getPoints() > 0 ? $this->object->getPoints() : '');
493 $points->setRequired(true);
494 $points->setSize(3);
495 $points->setMinValue(0.0);
496 $points->setMinvalueShouldBeGreater(true);
497 $form->addItem($points);
498
499 $header = new ilFormSectionHeaderGUI();
500 $header->setTitle($this->lng->txt("range"));
501 $form->addItem($header);
502
503 // lower bound
504 $lower_limit = new ilFormulaInputGUI($this->lng->txt("range_lower_limit"), "lowerlimit");
505 $lower_limit->setSize(25);
506 $lower_limit->setMaxLength(20);
507 $lower_limit->setRequired(true);
508 $lower_limit->setValue($this->object->getLowerLimit());
509 $form->addItem($lower_limit);
510
511 // upper bound
512 $upper_limit = new ilFormulaInputGUI($this->lng->txt("range_upper_limit"), "upperlimit");
513 $upper_limit->setSize(25);
514 $upper_limit->setMaxLength(20);
515 $upper_limit->setRequired(true);
516 $upper_limit->setValue($this->object->getUpperLimit());
517 $form->addItem($upper_limit);
518
519 // reset input length, if max chars are set
520 if ($this->object->getMaxChars() > 0) {
521 $lower_limit->setSize($this->object->getMaxChars());
522 $lower_limit->setMaxLength($this->object->getMaxChars());
523 $upper_limit->setSize($this->object->getMaxChars());
524 $upper_limit->setMaxLength($this->object->getMaxChars());
525 }
526 }
527
532 {
533 $this->object->setPoints((float) str_replace(',', '.', $form->getInput('points')));
534 $this->object->setLowerLimit((float) str_replace(',', '.', $form->getInput('lowerlimit')));
535 $this->object->setUpperLimit((float) str_replace(',', '.', $form->getInput('upperlimit')));
536 }
537}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
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.
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.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
__construct($id=-1)
assNumericGUI constructor
aggregateAnswers($relevant_answers_chosen)
writePostData(bool $always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getSpecificFeedbackOutput(array $userSolution)
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getPreview($show_question_only=false, $showInlineFeedback=false)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
renderAggregateView($aggregate)
getAnswersFrequency($relevantAnswers, $questionIndex)
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $inlineFeedback=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
populateTaxonomyFormSection(ilPropertyFormGUI $form)
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
getGenericFeedbackOutput(int $active_id, ?int $pass)
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
hasCorrectSolution($activeId, $passIndex)
generateCorrectnessIconsForCorrectness(int $correctness)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a number property in a property form.
This class represents a property form user interface.
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
special template class to simplify handling of ITX/PEAR
global $DIC
Definition: feed.php:28
$errors
Definition: imgupload.php:65
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193