ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 $this->object->loadFromDb($id);
43 }
44 }
45
46 public function getCommand($cmd)
47 {
48 if (substr($cmd, 0, 6) == "delete") {
49 $cmd = "delete";
50 }
51 return $cmd;
52 }
53
57 protected function writePostData($always = false)
58 {
59 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
60 if (!$hasErrors) {
61 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
66 return 0;
67 }
68 return 1;
69 }
70
78 public function editQuestion($checkonly = false)
79 {
80 $save = $this->isSaveCommand();
81 $this->getQuestionTemplate();
82
83 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
85 $this->editForm = $form;
86
87 $form->setFormAction($this->ctrl->getFormAction($this));
88 $form->setTitle($this->outQuestionType());
89 $form->setMultipart(true);
90 $form->setTableWidth("100%");
91 $form->setId("assnumeric");
92
98
99 $errors = false;
100
101 if ($save) {
102 $form->setValuesByPost();
103 $errors = !$form->checkInput();
104 $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
105
106 $lower = $form->getItemByPostVar('lowerlimit');
107 $upper = $form->getItemByPostVar('upperlimit');
108
109 if (!$this->checkRange($lower->getValue(), $upper->getValue())) {
110 global $DIC;
111 $lower->setAlert($DIC->language()->txt('qpl_numeric_lower_needs_valid_lower_alert'));
112 $upper->setAlert($DIC->language()->txt('qpl_numeric_upper_needs_valid_upper_alert'));
113 ilUtil::sendFailure($DIC->language()->txt("form_input_not_valid"));
114 $errors = true;
115 }
116
117 if ($errors) {
118 $checkonly = false;
119 }
120 }
121
122 if (!$checkonly) {
123 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
124 }
125 return $errors;
126 }
127
135 public function checkRange($lower, $upper)
136 {
137 include_once "./Services/Math/classes/class.EvalMath.php";
138 $eval = new EvalMath();
139 $eval->suppress_errors = true;
140 if (($eval->e($lower) !== false) and ($eval->e($upper) !== false)) {
141 if ($eval->e($lower) <= $eval->e($upper)) {
142 return true;
143 } else {
144 return false;
145 }
146 }
147 return false;
148 }
149
165 public function getSolutionOutput(
166 $active_id,
167 $pass = null,
168 $graphicalOutput = false,
169 $result_output = false,
170 $show_question_only = true,
171 $show_feedback = false,
172 $show_correct_solution = false,
173 $show_manual_scoring = false,
174 $show_question_text = true
175 ) {
176 // get the solution of the user for the active pass or from the last pass if allowed
177 $solutions = array();
178 if (($active_id > 0) && (!$show_correct_solution)) {
179 $solutions =&$this->object->getSolutionValues($active_id, $pass);
180 } else {
181 array_push($solutions, array("value1" => sprintf($this->lng->txt("value_between_x_and_y"), $this->object->getLowerLimit(), $this->object->getUpperLimit())));
182 }
183
184 // generate the question output
185 require_once './Services/UICore/classes/class.ilTemplate.php';
186 $template = new ilTemplate("tpl.il_as_qpl_numeric_output_solution.html", true, true, "Modules/TestQuestionPool");
187 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
188 if (is_array($solutions)) {
189 if (($active_id > 0) && (!$show_correct_solution)) {
190 if ($graphicalOutput) {
191 if ($this->object->getStep() === null) {
192 $reached_points = $this->object->getReachedPoints($active_id, $pass);
193 } else {
194 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
195 }
196 // output of ok/not ok icons for user entered solutions
197 if ($reached_points == $this->object->getMaximumPoints()) {
198 $template->setCurrentBlock("icon_ok");
199 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
200 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
201 $template->parseCurrentBlock();
202 } else {
203 $template->setCurrentBlock("icon_ok");
204 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
205 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
206 $template->parseCurrentBlock();
207 }
208 }
209 }
210 foreach ($solutions as $solution) {
211 $template->setVariable("NUMERIC_VALUE", $solution["value1"]);
212 }
213 if (count($solutions) == 0) {
214 $template->setVariable("NUMERIC_VALUE", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
215 }
216 }
217 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
218 $questiontext = $this->object->getQuestion();
219 if ($show_question_text==true) {
220 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
221 }
222 $questionoutput = $template->get();
223 //$feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : ""; // Moving new method
224 // due to deprecation.
225 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput($active_id, $pass) : "";
226 if (strlen($feedback)) {
227 $cssClass = (
228 $this->hasCorrectSolution($active_id, $pass) ?
230 );
231
232 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
233 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
234 }
235 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
236
237 $solutionoutput = $solutiontemplate->get();
238 if (!$show_question_only) {
239 // get page object output
240 $solutionoutput = $this->getILIASPage($solutionoutput);
241 }
242 return $solutionoutput;
243 }
244
250 public function getPreview($show_question_only = false, $showInlineFeedback = false)
251 {
252 // generate the question output
253 require_once './Services/UICore/classes/class.ilTemplate.php';
254 $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", true, true, "Modules/TestQuestionPool");
255 if (is_object($this->getPreviewSession())) {
256 $template->setVariable("NUMERIC_VALUE", " value=\"" . $this->getPreviewSession()->getParticipantsSolution() . "\"");
257 }
258 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
259 $questiontext = $this->object->getQuestion();
260 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
261 $questionoutput = $template->get();
262 if (!$show_question_only) {
263 // get page object output
264 $questionoutput = $this->getILIASPage($questionoutput);
265 }
266 return $questionoutput;
267 }
268
277 // hey: prevPassSolutions - pass will be always available from now on
278 public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $inlineFeedback)
279 // hey.
280 {
281 $solutions = null;
282 // get the solution of the user for the active pass or from the last pass if allowed
283 if ($use_post_solutions !== false) {
284 $solutions = array(
285 array('value1' => $use_post_solutions['numeric_result'])
286 );
287 } elseif ($active_id) {
288
289 // hey: prevPassSolutions - obsolete due to central check
290 #include_once "./Modules/Test/classes/class.ilObjTest.php";
291 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
292 #{
293 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
294 #}
295 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
296 // hey.
297 }
298
299 // generate the question output
300 require_once './Services/UICore/classes/class.ilTemplate.php';
301 $template = new ilTemplate("tpl.il_as_qpl_numeric_output.html", true, true, "Modules/TestQuestionPool");
302 if (is_array($solutions)) {
303 foreach ($solutions as $solution) {
304 $template->setVariable("NUMERIC_VALUE", " value=\"" . $solution["value1"] . "\"");
305 }
306 }
307 $template->setVariable("NUMERIC_SIZE", $this->object->getMaxChars());
308 $questiontext = $this->object->getQuestion();
309 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
310 $questionoutput = $template->get();
311 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
312 return $pageoutput;
313 }
314
320 public function setQuestionTabs()
321 {
324 global $rbacsystem, $ilTabs;
325
326 $ilTabs->clearTargets();
327
328 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
329 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
330 $q_type = $this->object->getQuestionType();
331
332 if (strlen($q_type)) {
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 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
340 // edit page
341 $ilTabs->addTarget(
342 "edit_page",
343 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
344 array("edit", "insert", "exec_pg"),
345 "",
346 "",
347 $force_active
348 );
349 }
350
351 $this->addTab_QuestionPreview($ilTabs);
352 }
353
354 $force_active = false;
355 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
356 $url = "";
357 if ($classname) {
358 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
359 }
360 // edit question properties
361 $ilTabs->addTarget(
362 "edit_question",
363 $url,
364 array("editQuestion", "save", "cancel", "saveEdit", "originalSyncForm"),
365 $classname,
366 "",
367 $force_active
368 );
369 }
370
371 // add tab for question feedback within common class assQuestionGUI
372 $this->addTab_QuestionFeedback($ilTabs);
373
374 // add tab for question hint within common class assQuestionGUI
375 $this->addTab_QuestionHints($ilTabs);
376
377 // add tab for question's suggested solution within common class assQuestionGUI
378 $this->addTab_SuggestedSolution($ilTabs, $classname);
379
380 // Assessment of questions sub menu entry
381 if ($_GET["q_id"]) {
382 $ilTabs->addTarget(
383 "statistics",
384 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
385 array("assessment"),
386 $classname,
387 ""
388 );
389 }
390
391 $this->addBackTab($ilTabs);
392 }
393
400 public function getSpecificFeedbackOutput($active_id, $pass)
401 {
402 $output = "";
403 return $this->object->prepareTextareaOutput($output, true);
404 }
405
407 {
408 $this->object->setMaxChars($_POST["maxchars"]);
409 }
410
412 {
413 $this->object->setLowerLimit($_POST['lowerlimit']);
414 $this->object->setUpperLimit($_POST['upperlimit']);
415 $this->object->setPoints($_POST['points']);
416 }
417
419 {
420 // maxchars
421 $maxchars = new ilNumberInputGUI($this->lng->txt("maxchars"), "maxchars");
422 $maxchars->setInfo($this->lng->txt('qpl_maxchars_info_numeric_question'));
423 $maxchars->setSize(10);
424 $maxchars->setDecimals(0);
425 $maxchars->setMinValue(1);
426 $maxchars->setRequired(true);
427 if ($this->object->getMaxChars() > 0) {
428 $maxchars->setValue($this->object->getMaxChars());
429 }
430 $form->addItem($maxchars);
431 }
432
434 {
435 // points
436 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
437 $points->allowDecimals(true);
438 $points->setValue($this->object->getPoints() > 0 ? $this->object->getPoints() : '');
439 $points->setRequired(true);
440 $points->setSize(3);
441 $points->setMinValue(0.0);
442 $points->setMinvalueShouldBeGreater(true);
443 $form->addItem($points);
444
446 $header->setTitle($this->lng->txt("range"));
447 $form->addItem($header);
448
449 // lower bound
450 $lower_limit = new ilFormulaInputGUI($this->lng->txt("range_lower_limit"), "lowerlimit");
451 $lower_limit->setSize(25);
452 $lower_limit->setMaxLength(20);
453 $lower_limit->setRequired(true);
454 $lower_limit->setValue($this->object->getLowerLimit());
455 $form->addItem($lower_limit);
456
457 // upper bound
458 $upper_limit = new ilFormulaInputGUI($this->lng->txt("range_upper_limit"), "upperlimit");
459 $upper_limit->setSize(25);
460 $upper_limit->setMaxLength(20);
461 $upper_limit->setRequired(true);
462 $upper_limit->setValue($this->object->getUpperLimit());
463 $form->addItem($upper_limit);
464
465 // reset input length, if max chars are set
466 if ($this->object->getMaxChars() > 0) {
467 $lower_limit->setSize($this->object->getMaxChars());
468 $lower_limit->setMaxLength($this->object->getMaxChars());
469 $upper_limit->setSize($this->object->getMaxChars());
470 $upper_limit->setMaxLength($this->object->getMaxChars());
471 }
472 }
473
484 {
485 return array();
486 }
487
498 {
499 return array();
500 }
501
510 public function getAggregatedAnswersView($relevant_answers)
511 {
512 return $this->renderAggregateView(
513 $this->aggregateAnswers($relevant_answers)
514 )->get();
515 }
516
517 public function aggregateAnswers($relevant_answers_chosen)
518 {
519 $aggregate = array();
520
521 foreach ($relevant_answers_chosen as $relevant_answer) {
522 if (array_key_exists($relevant_answer['value1'], $aggregate)) {
523 $aggregate[$relevant_answer['value1']]++;
524 } else {
525 $aggregate[$relevant_answer['value1']] = 1;
526 }
527 }
528 return $aggregate;
529 }
530
536 public function renderAggregateView($aggregate)
537 {
538 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
539
540 $tpl->setCurrentBlock('headercell');
541 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
542 $tpl->parseCurrentBlock();
543
544 $tpl->setCurrentBlock('headercell');
545 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
546 $tpl->parseCurrentBlock();
547
548 foreach ($aggregate as $key => $value) {
549 $tpl->setCurrentBlock('aggregaterow');
550 $tpl->setVariable('OPTION', $key);
551 $tpl->setVariable('COUNT', $value);
552 $tpl->parseCurrentBlock();
553 }
554 return $tpl;
555 }
556}
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.
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.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
getSpecificFeedbackOutput($active_id, $pass)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
__construct($id=-1)
assNumericGUI constructor
aggregateAnswers($relevant_answers_chosen)
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getPreview($show_question_only=false, $showInlineFeedback=false)
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...
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
renderAggregateView($aggregate)
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $inlineFeedback)
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.
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)
$template
$key
Definition: croninfo.php:18
if(!array_key_exists('StateId', $_REQUEST)) $id
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$errors
Definition: index.php:6
$url
if(isset($_POST['submit'])) $form
global $DIC
Definition: saml.php:7