ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.assNumericGUI.php
Go to the documentation of this file.
1<?php
2
36{
44 public function __construct($id = -1)
45 {
47 $this->object = new assNumeric();
48 if ($id >= 0) {
49 $this->object->loadFromDb($id);
50 }
51 }
52
53 public function getCommand($cmd)
54 {
55 if (substr($cmd, 0, 6) == "delete") {
56 $cmd = "delete";
57 }
58 return $cmd;
59 }
60
64 protected function writePostData(bool $always = false): int
65 {
66 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
67 if (!$hasErrors) {
72 return 0;
73 }
74 return 1;
75 }
76
77 public function editQuestion(
78 bool $checkonly = false,
79 ?bool $is_save_cmd = null
80 ): bool {
81 $save = $is_save_cmd ?? $this->isSaveCommand();
82
83 $form = new ilPropertyFormGUI();
84 $this->editForm = $form;
85
86 $form->setFormAction($this->ctrl->getFormAction($this));
87 $form->setTitle($this->outQuestionType());
88 $form->setMultipart(true);
89 $form->setTableWidth("100%");
90 $form->setId("assnumeric");
91
95 $this->populateTaxonomyFormSection($form);
97
98 $errors = false;
99
100 if ($save) {
101 $form->setValuesByPost();
102 $errors = !$form->checkInput();
103 $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
104
105 $lower = $form->getItemByPostVar('lowerlimit');
106 $upper = $form->getItemByPostVar('upperlimit');
107
108 $to_float_trafo = $this->refinery->byTrying([
109 $this->refinery->kindlyTo()->float(),
110 $this->refinery->always(0.0)
111 ]);
112
113 if (!$this->checkRange(
114 $to_float_trafo->transform($lower->getValue()),
115 $to_float_trafo->transform($upper->getValue())
116 )) {
117 global $DIC;
118 $lower->setAlert($DIC->language()->txt('qpl_numeric_lower_needs_valid_lower_alert'));
119 $upper->setAlert($DIC->language()->txt('qpl_numeric_upper_needs_valid_upper_alert'));
120 $this->tpl->setOnScreenMessage('failure', $DIC->language()->txt("form_input_not_valid"));
121 $errors = true;
122 }
123
124 if ($errors) {
125 $checkonly = false;
126 }
127 }
128
129 if (!$checkonly) {
130 $this->renderEditForm($form);
131 }
132 return $errors;
133 }
134
135 public function checkRange(float $lower, float $upper): bool
136 {
137 $eval = new EvalMath();
138 $eval->suppress_errors = true;
139 if (($eval->e($lower) !== false) and ($eval->e($upper) !== false)) {
140 if ($eval->e($lower) <= $eval->e($upper)) {
141 return true;
142 } else {
143 return false;
144 }
145 }
146 return false;
147 }
148
149 public function getSolutionOutput(
150 int $active_id,
151 ?int $pass = null,
152 bool $graphical_output = false,
153 bool $result_output = false,
154 bool $show_question_only = true,
155 bool $show_feedback = false,
156 bool $show_correct_solution = false,
157 bool $show_manual_scoring = false,
158 bool $show_question_text = true,
159 bool $show_inline_feedback = true
160 ): string {
161 // get the solution of the user for the active pass or from the last pass if allowed
162 $solutions = [];
163 if (($active_id > 0) && (!$show_correct_solution)) {
164 $solutions = $this->object->getSolutionValues($active_id, $pass);
165 } else {
166 array_push($solutions, [
167 'value1' => sprintf(
168 $this->lng->txt("value_between_x_and_y"),
169 $this->object->getLowerLimit(),
170 $this->object->getUpperLimit()
171 )
172 ]);
173 }
174
175 return $this->renderSolutionOutput(
176 $solutions,
177 $active_id,
178 $pass,
179 $graphical_output,
180 $result_output,
181 $show_question_only,
182 $show_feedback,
183 $show_correct_solution,
184 $show_manual_scoring,
185 $show_question_text,
186 false,
187 $show_inline_feedback
188 );
189 }
190
191 public function renderSolutionOutput(
192 mixed $user_solutions,
193 int $active_id,
194 ?int $pass,
195 bool $graphical_output = false,
196 bool $result_output = false,
197 bool $show_question_only = true,
198 bool $show_feedback = false,
199 bool $show_correct_solution = false,
200 bool $show_manual_scoring = false,
201 bool $show_question_text = true,
202 bool $show_autosave_title = false,
203 bool $show_inline_feedback = false,
204 ): ?string {
205 $template = new ilTemplate("tpl.il_as_qpl_numeric_output_solution.html", true, true, "components/ILIAS/TestQuestionPool");
206 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "components/ILIAS/TestQuestionPool");
207 if (is_array($user_solutions)) {
208 if (($active_id > 0) && (!$show_correct_solution)) {
209 if ($graphical_output) {
210 if ($this->object->getStep() === null) {
211 $reached_points = $this->object->getReachedPoints($active_id, $pass);
212 } else {
213 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
214 }
215
216 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
217 if ($reached_points == $this->object->getMaximumPoints()) {
218 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
219 }
220 $template->setCurrentBlock("icon_ok");
221 $template->setVariable("ICON_OK", $correctness_icon);
222 $template->parseCurrentBlock();
223 }
224 }
225 foreach ($user_solutions as $solution) {
226 $template->setVariable("NUMERIC_VALUE", $solution['value1']);
227 }
228 if (count($user_solutions) == 0) {
229 $template->setVariable("NUMERIC_VALUE", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
230 }
231 }
232 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
233 if ($show_question_text == true) {
234 $template->setVariable("QUESTIONTEXT", $this->renderLatex($this->object->getQuestionForHTMLOutput()));
235 }
236 $questionoutput = $template->get();
237 //$feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : ""; // Moving new method
238 // due to deprecation.
239 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput((int) $active_id, $pass) : "";
240 if (strlen($feedback)) {
241 $cssClass = (
242 $this->hasCorrectSolution($active_id, $pass) ?
244 );
245
246 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
247 $solutiontemplate->setVariable("FEEDBACK", ilLegacyFormElementsUtil::prepareTextareaOutput($feedback, true));
248 }
249 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
250
251 $solutionoutput = $solutiontemplate->get();
252 if (!$show_question_only) {
253 // get page object output
254 $solutionoutput = $this->getILIASPage($solutionoutput);
255 }
256 return $solutionoutput;
257 }
258
259 public function getPreview(
260 bool $show_question_only = false,
261 bool $show_inline_feedback = false
262 ): string {
263 // generate the question output
264 $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", true, true, "components/ILIAS/TestQuestionPool");
265 if (is_object($this->getPreviewSession())) {
266 $template->setVariable("NUMERIC_VALUE", " value=\"" . $this->getPreviewSession()->getParticipantsSolution() . "\"");
267 }
268 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
269 $template->setVariable("QUESTIONTEXT", $this->renderLatex($this->object->getQuestionForHTMLOutput()));
270 $questionoutput = $template->get();
271 if (!$show_question_only) {
272 // get page object output
273 $questionoutput = $this->getILIASPage($questionoutput);
274 }
275 return $questionoutput;
276 }
277
278 public function getTestOutput(
279 int $active_id,
280 int $pass,
281 bool $is_question_postponed = false,
282 array|bool $user_post_solutions = false,
283 bool $show_specific_inline_feedback = false
284 ): string {
285 $solutions = null;
286 // get the solution of the user for the active pass or from the last pass if allowed
287 if ($user_post_solutions !== false) {
289 $solutions = [
290 ['value1' => $user_post_solutions['numeric_result']]
291 ];
292 } elseif ($active_id) {
293 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
294 }
295
296 // generate the question output
297 $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", true, true, "components/ILIAS/TestQuestionPool");
298 if (is_array($solutions)) {
299 foreach ($solutions as $solution) {
300 $template->setVariable("NUMERIC_VALUE", " value=\"" . $solution['value1'] . "\"");
301 }
302 }
303 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
304 $template->setVariable("QUESTIONTEXT", $this->renderLatex($this->object->getQuestionForHTMLOutput()));
305 $questionoutput = $template->get();
306 $pageoutput = $this->outQuestionPage("", $is_question_postponed, $active_id, $questionoutput);
307 return $pageoutput;
308 }
309
315 public function getSpecificFeedbackOutput(array $userSolution): string
316 {
317 $output = "";
319 }
320
322 {
323 $this->object->setMaxChars($this->request_data_collector->int('maxchars') ?? 6);
324 }
325
327 {
328 $this->object->setLowerLimit($this->request_data_collector->float('lowerlimit'));
329 $this->object->setUpperLimit($this->request_data_collector->float('upperlimit'));
330 $this->object->setPoints($this->request_data_collector->float('points'));
331 }
332
334 {
335 // maxchars
336 $maxchars = new ilNumberInputGUI($this->lng->txt("maxchars"), "maxchars");
337 $maxchars->setInfo($this->lng->txt('qpl_maxchars_info_numeric_question'));
338 $maxchars->setSize(10);
339 $maxchars->setDecimals(0);
340 $maxchars->setMinValue(1);
341 $maxchars->setRequired(true);
342 if ($this->object->getMaxChars() > 0) {
343 $maxchars->setValue($this->object->getMaxChars());
344 }
345 $form->addItem($maxchars);
346 return $form;
347 }
348
350 {
351 // points
352 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
353 $points->allowDecimals(true);
354 $points->setValue($this->object->getPoints() > 0 ? $this->object->getPoints() : '');
355 $points->setRequired(true);
356 $points->setSize(3);
357 $points->setMinValue(0.0);
358 $points->setMinvalueShouldBeGreater(true);
359 $form->addItem($points);
360
361 $header = new ilFormSectionHeaderGUI();
362 $header->setTitle($this->lng->txt("range"));
363 $form->addItem($header);
364
365 // lower bound
366 $lower_limit = new ilFormulaInputGUI($this->lng->txt("range_lower_limit"), "lowerlimit");
367 $lower_limit->setSize(25);
368 $lower_limit->setMaxLength(20);
369 $lower_limit->setRequired(true);
370 $lower_limit->setValue((string) $this->object->getLowerLimit());
371 $form->addItem($lower_limit);
372
373 // upper bound
374 $upper_limit = new ilFormulaInputGUI($this->lng->txt("range_upper_limit"), "upperlimit");
375 $upper_limit->setSize(25);
376 $upper_limit->setMaxLength(20);
377 $upper_limit->setRequired(true);
378 $upper_limit->setValue((string) $this->object->getUpperLimit());
379 $form->addItem($upper_limit);
380
381 // reset input length, if max chars are set
382 if ($this->object->getMaxChars() > 0) {
383 $lower_limit->setSize($this->object->getMaxChars());
384 $lower_limit->setMaxLength($this->object->getMaxChars());
385 $upper_limit->setSize($this->object->getMaxChars());
386 $upper_limit->setMaxLength($this->object->getMaxChars());
387 }
388 return $form;
389 }
390
401 {
402 return [];
403 }
404
415 {
416 return [];
417 }
418
419 public function getAnswersFrequency($relevantAnswers, $questionIndex): array
420 {
421 $answers = [];
422
423 foreach ($relevantAnswers as $ans) {
424 if (!isset($answers[$ans['value1']])) {
425 $answers[$ans['value1']] = [
426 'answer' => $ans['value1'], 'frequency' => 0
427 ];
428 }
429
430 $answers[$ans['value1']]['frequency']++;
431 }
432
433 return $answers;
434 }
435
437 {
438 // points
439 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
440 $points->allowDecimals(true);
441 $points->setValue($this->object->getPoints() > 0 ? $this->object->getPoints() : '');
442 $points->setRequired(true);
443 $points->setSize(3);
444 $points->setMinValue(0.0);
445 $points->setMinvalueShouldBeGreater(true);
446 $form->addItem($points);
447
448 $header = new ilFormSectionHeaderGUI();
449 $header->setTitle($this->lng->txt("range"));
450 $form->addItem($header);
451
452 // lower bound
453 $lower_limit = new ilFormulaInputGUI($this->lng->txt("range_lower_limit"), "lowerlimit");
454 $lower_limit->setSize(25);
455 $lower_limit->setMaxLength(20);
456 $lower_limit->setRequired(true);
457 $lower_limit->setValue($this->object->getLowerLimit());
458 $form->addItem($lower_limit);
459
460 // upper bound
461 $upper_limit = new ilFormulaInputGUI($this->lng->txt("range_upper_limit"), "upperlimit");
462 $upper_limit->setSize(25);
463 $upper_limit->setMaxLength(20);
464 $upper_limit->setRequired(true);
465 $upper_limit->setValue($this->object->getUpperLimit());
466 $form->addItem($upper_limit);
467
468 // reset input length, if max chars are set
469 if ($this->object->getMaxChars() > 0) {
470 $lower_limit->setSize($this->object->getMaxChars());
471 $lower_limit->setMaxLength($this->object->getMaxChars());
472 $upper_limit->setSize($this->object->getMaxChars());
473 $upper_limit->setMaxLength($this->object->getMaxChars());
474 }
475 }
476
481 {
482 $this->object->setPoints((float) str_replace(',', '.', $form->getInput('points')));
483 $this->object->setLowerLimit((float) str_replace(',', '.', $form->getInput('lowerlimit')));
484 $this->object->setUpperLimit((float) str_replace(',', '.', $form->getInput('upperlimit')));
485 }
486}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:544
return true
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 the request and applies them to the data object.
getPreview(bool $show_question_only=false, bool $show_inline_feedback=false)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from the request and applies them to the data object.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
getTestOutput(int $active_id, int $pass, bool $is_question_postponed=false, array|bool $user_post_solutions=false, bool $show_specific_inline_feedback=false)
renderSolutionOutput(mixed $user_solutions, int $active_id, ?int $pass, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_autosave_title=false, bool $show_inline_feedback=false,)
__construct($id=-1)
assNumericGUI constructor
editQuestion(bool $checkonly=false, ?bool $is_save_cmd=null)
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)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
getSolutionOutput(int $active_id, ?int $pass=null, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_inline_feedback=true)
getAnswersFrequency($relevantAnswers, $questionIndex)
checkRange(float $lower, float $upper)
Class for numeric questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
renderEditForm(ilPropertyFormGUI $form)
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
This class represents a section header in a property form.
This class represents a formula text property in a property form.
static prepareTextareaOutput(string $txt_output, bool $prepare_for_latex_output=false, bool $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free,...
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
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...
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $DIC
Definition: shib_login.php:26