ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assFormulaQuestion.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
5include_once "./Modules/TestQuestionPool/classes/class.assFormulaQuestionResult.php";
6include_once "./Modules/TestQuestionPool/classes/class.assFormulaQuestionVariable.php";
7include_once "./Modules/TestQuestionPool/classes/class.ilUnitConfigurationRepository.php";
8include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
9include_once "./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php";
10require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
11
20{
21 private $variables;
22 private $results;
23 private $resultunits;
24
29
41 public function __construct(
42 $title = "",
43 $comment = "",
44 $author = "",
45 $owner = -1,
46 $question = ""
47 ) {
48 parent::__construct($title, $comment, $author, $owner, $question);
49 $this->variables = array();
50 $this->results = array();
51 $this->resultunits = array();
52 $this->unitrepository = new ilUnitConfigurationRepository(0);
53 }
54
55 public function clearVariables()
56 {
57 $this->variables = array();
58 }
59
60 public function getVariables()
61 {
62 return $this->variables;
63 }
64
65 public function getVariable($variable)
66 {
67 if (array_key_exists($variable, $this->variables)) {
68 return $this->variables[$variable];
69 }
70 return null;
71 }
72
73 public function addVariable($variable)
74 {
75 $this->variables[$variable->getVariable()] = $variable;
76 }
77
78 public function clearResults()
79 {
80 $this->results = array();
81 }
82
83 public function getResults()
84 {
85 return $this->results;
86 }
87
88 public function getResult($result)
89 {
90 if (array_key_exists($result, $this->results)) {
91 return $this->results[$result];
92 }
93 return null;
94 }
95
96 public function addResult($result)
97 {
98 $this->results[$result->getResult()] = $result;
99 }
100
101 public function addResultUnits($result, $unit_ids)
102 {
103 $this->resultunits[$result->getResult()] = array();
104 if ((!is_object($result)) || (!is_array($unit_ids))) {
105 return;
106 }
107 foreach ($unit_ids as $id) {
108 if (is_numeric($id) && ($id > 0)) {
109 $this->resultunits[$result->getResult()][$id] = $this->getUnitrepository()->getUnit($id);
110 }
111 }
112 }
113
114 public function addResultUnit($result, $unit)
115 {
116 if (is_object($result) && is_object($unit)) {
117 if (!is_array($this->resultunits[$result->getResult()])) {
118 $this->resultunits[$result->getResult()] = array();
119 }
120 $this->resultunits[$result->getResult()][$unit->getId()] = $unit;
121 }
122 }
123
124 public function getResultUnits($result)
125 {
126 if (array_key_exists($result->getResult(), $this->resultunits)) {
127 return $this->resultunits[$result->getResult()];
128 } else {
129 return array();
130 }
131 }
132
133 public function hasResultUnit($result, $unit_id)
134 {
135 if (array_key_exists($result->getResult(), $this->resultunits)) {
136 if (array_key_exists($unit_id, $this->resultunits[$result->getResult()])) {
137 return true;
138 }
139 }
140
141 return false;
142 }
143
144 public function parseQuestionText()
145 {
146 $this->clearResults();
147 $this->clearVariables();
148 if (preg_match_all("/(\\\$v\\d+)/ims", $this->getQuestion(), $matches)) {
149 foreach ($matches[1] as $variable) {
150 $varObj = new assFormulaQuestionVariable($variable, 0, 0, null, 0);
151 $this->addVariable($varObj);
152 }
153 }
154
155 if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
156 foreach ($rmatches[1] as $result) {
157 $resObj = new assFormulaQuestionResult($result, null, null, 0, -1, null, 1, 1, true);
158 $this->addResult($resObj);
159 }
160 }
161 }
162
164 {
165 if (preg_match_all("/(\\\$v\\d+)/ims", $this->getQuestion(), $matches)) {
166 if ((count(array_unique($matches[1]))) != count($matches[1])) {
167 return false;
168 }
169 }
170 return true;
171 }
172
173 public function checkForDuplicateResults()
174 {
175 if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
176 if ((count(array_unique($rmatches[1]))) != count($rmatches[1])) {
177 return false;
178 }
179 }
180 return true;
181 }
182
187 public function fetchAllResults($questionText)
188 {
189 $resObjects = array();
190 $matches = null;
191
192 if (preg_match_all("/(\\\$r\\d+)/ims", $questionText, $matches)) {
193 foreach ($matches[1] as $resultKey) {
194 $resObjects[] = $this->getResult($resultKey);
195 }
196 }
197
198 return $resObjects;
199 }
200
205 public function fetchAllVariables($questionText)
206 {
207 $varObjects = array();
208 $matches = null;
209
210 if (preg_match_all("/(\\\$v\\d+)/ims", $questionText, $matches)) {
211 foreach ($matches[1] as $variableKey) {
212 $varObjects[] = $this->getVariable($variableKey);
213 }
214 }
215
216 return $varObjects;
217 }
218
223 public function hasRequiredVariableSolutionValues(array $userSolution)
224 {
225 foreach ($this->fetchAllVariables($this->getQuestion()) as $varObj) {
226 if (!isset($userSolution[$varObj->getVariable()])) {
227 return false;
228 }
229
230 if (!strlen($userSolution[$varObj->getVariable()])) {
231 return false;
232 }
233 }
234
235 return true;
236 }
237
242 {
243 foreach ($this->fetchAllResults($this->getQuestion()) as $resObj) {
244 $resObj->findValidRandomVariables($this->getVariables(), $this->getResults());
245 }
246
247 $variableSolutionValues = array();
248
249 foreach ($this->fetchAllVariables($this->getQuestion()) as $varObj) {
250 $variableSolutionValues[$varObj->getVariable()] = $varObj->getValue();
251 }
252
253 return $variableSolutionValues;
254 }
255
264 public function substituteVariables(array $userdata, $graphicalOutput = false, $forsolution = false, $result_output = false)
265 {
266 if ((count($this->results) == 0) && (count($this->variables) == 0)) {
267 return false;
268 }
269
270 $text = $this->getQuestion();
271
272 foreach ($this->fetchAllVariables($this->getQuestion()) as $varObj) {
273 if (isset($userdata[$varObj->getVariable()]) && strlen($userdata[$varObj->getVariable()])) {
274 $varObj->setValue($userdata[$varObj->getVariable()]);
275 }
276
277 $unit = (is_object($varObj->getUnit())) ? $varObj->getUnit()->getUnit() : "";
278 $val = (strlen($varObj->getValue()) > 8) ? strtoupper(sprintf("%e", $varObj->getValue())) : $varObj->getValue();
279
280 $text = preg_replace("/\\$" . substr($varObj->getVariable(), 1) . "(?![0-9]+)/", $val . " " . $unit . "\\1", $text);
281 }
282
283 if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
284 foreach ($rmatches[1] as $result) {
285 $resObj = $this->getResult($result);
286 $value = "";
287 $frac_helper = '';
288 $user_data[$result]['result_type'] = $resObj->getResultType();
289
290 if (
291 $resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC ||
292 $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC
293 ) {
294 $is_frac = true;
295 }
296 if (is_array($userdata)) {
297 if (is_array($userdata[$result])) {
298 if (false && $forsolution && $result_output) { // fix for mantis #25956
299 $value_org = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
300 $value = sprintf("%." . $resObj->getPrecision() . "f", $value_org);
301 if ($is_frac) {
303 if (is_array($value)) {
304 $frac_helper = $value[1];
305 $value = $value[0];
306 }
307 }
308 } else {
309 if ($forsolution) {
310 $value = $userdata[$result]["value"];
311 } else {
312 $value = ' value="' . $userdata[$result]["value"] . '"';
313 }
314 }
315 }
316 } else {
317 if ($forsolution) {
318 $value = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
319 $value = sprintf("%." . $resObj->getPrecision() . "f", $value);
320
321 if ($is_frac) {
323 if (is_array($value)) {
324 $frac_helper = $value[1];
325 $value = $value[0];
326 }
327 $value = ' value="' . $value . '"';
328 }
329 } else {
330 // Precision fix for Preview by tjoussen
331 // If all default values are set, this function is called in getPreview
332 $use_precision = !($userdata == null && $graphicalOutput == false && $forsolution == false && $result_output == false);
333
334 $val = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), $use_precision);
335
336 if ($resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC
337 || $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC) {
338 $val = $resObj->convertDecimalToCoprimeFraction($val);
339 if (is_array($val)) {
340 $frac_helper = $val[1];
341 $val = $val[0];
342 }
343 } else {
344 $val = sprintf("%." . $resObj->getPrecision() . "f", $val);
345 $val = (strlen($val) > 8) ? strtoupper(sprintf("%e", $val)) : $val;
346 }
347 $value = ' value="' . $val . '"';
348 }
349 }
350
351 if ($forsolution) {
352 $input = '<span class="ilc_qinput_TextInput solutionbox">' . ilUtil::prepareFormOutput($value) . '</span>';
353 } else {
354 $input = '<input class="ilc_qinput_TextInput" type="text" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" name="result_' . $result . '"' . $value . ' />';
355 }
356
357 $units = "";
358 if (count($this->getResultUnits($resObj)) > 0) {
359 if ($forsolution) {
360 if (is_array($userdata)) {
361 foreach ($this->getResultUnits($resObj) as $unit) {
362 if ($userdata[$result]["unit"] == $unit->getId()) {
363 $units = $unit->getUnit();
364 }
365 }
366 } else {
367 if ($resObj->getUnit()) {
368 $units = $resObj->getUnit()->getUnit();
369 }
370 }
371 } else {
372 $units = '<select name="result_' . $result . '_unit">';
373 $units .= '<option value="-1">' . $this->lng->txt("select_unit") . '</option>';
374 foreach ($this->getResultUnits($resObj) as $unit) {
375 $units .= '<option value="' . $unit->getId() . '"';
376 if ((is_array($userdata[$result])) && (strlen($userdata[$result]["unit"]))) {
377 if ($userdata[$result]["unit"] == $unit->getId()) {
378 $units .= ' selected="selected"';
379 }
380 }
381 $units .= '>' . $unit->getUnit() . '</option>';
382 }
383 $units .= '</select>';
384 }
385 } else {
386 $units = "";
387 }
388 switch ($resObj->getResultType()) {
390 $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_dec');
391 break;
393 if (strlen($frac_helper)) {
394 $units .= ' &asymp; ' . $frac_helper . ', ';
395 } elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"])) {
396 if (!preg_match('-/-', $value)) {
397 $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
398 }
399 }
400 $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_frac');
401 break;
403 if (strlen($frac_helper)) {
404 $units .= ' &asymp; ' . $frac_helper . ', ';
405 } elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"])) {
406 if (!preg_match('-/-', $value)) {
407 $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
408 }
409 }
410 $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_co_frac');
411 break;
413 break;
414 }
415 $checkSign = "";
416 if ($graphicalOutput) {
417 $resunit = null;
418 $user_value = '';
419 if (is_array($userdata) && is_array($userdata[$result])) {
420 if ($userdata[$result]["unit"] > 0) {
421 $resunit = $this->getUnitrepository()->getUnit($userdata[$result]["unit"]);
422 }
423
424 if (isset($userdata[$result]["value"])) {
425 $user_value = $userdata[$result]["value"];
426 }
427 }
428
429 $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_image.html", true, true, 'Modules/TestQuestionPool');
430
431 if ($resObj->isCorrect($this->getVariables(), $this->getResults(), $user_value, $resunit)) {
432 $template->setCurrentBlock("icon_ok");
433 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
434 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
435 $template->parseCurrentBlock();
436 } else {
437 $template->setCurrentBlock("icon_not_ok");
438 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
439 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
440 $template->parseCurrentBlock();
441 }
442 $checkSign = $template->get();
443 }
444 $resultOutput = "";
445 if ($result_output) {
446 $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_result.html", true, true, 'Modules/TestQuestionPool');
447
448 if (is_array($userdata)) {
449 $found = $resObj->getResultInfo($this->getVariables(), $this->getResults(), $userdata[$resObj->getResult()]["value"], $userdata[$resObj->getResult()]["unit"], $this->getUnitrepository()->getUnits());
450 } else {
451 $found = $resObj->getResultInfo($this->getVariables(), $this->getResults(), $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId()), is_object($resObj->getUnit()) ? $resObj->getUnit()->getId() : null, $this->getUnitrepository()->getUnits());
452 }
453 $resulttext = "(";
454 if ($resObj->getRatingSimple()) {
455 if ($frac_helper) {
456 $resulttext .= "n/a";
457 } else {
458 $resulttext .= $found['points'] . " " . (($found['points'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
459 }
460 } else {
461 $resulttext .= $this->lng->txt("rated_sign") . " " . (($found['sign']) ? $found['sign'] : 0) . " " . (($found['sign'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
462 $resulttext .= $this->lng->txt("rated_value") . " " . (($found['value']) ? $found['value'] : 0) . " " . (($found['value'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
463 $resulttext .= $this->lng->txt("rated_unit") . " " . (($found['unit']) ? $found['unit'] : 0) . " " . (($found['unit'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
464 }
465
466 $resulttext .= ")";
467 $template->setVariable("RESULT_OUTPUT", $resulttext);
468
469 $resultOutput = $template->get();
470 }
471 $text = preg_replace("/\\\$" . substr($result, 1) . "(?![0-9]+)/", $input . " " . $units . " " . $checkSign . " " . $resultOutput . " " . "\\1", $text);
472 }
473 }
474 return $text;
475 }
476
484 {
485 $result_units = $this->getResultUnits($result);
486 $resultunit = $result->getUnit();
487 $similar_units = 0;
488 foreach ($result_units as $unit) {
489 if (is_object($resultunit)) {
490 if ($resultunit->getId() != $unit->getId()) {
491 if ($resultunit->getBaseUnit() && $unit->getBaseUnit()) {
492 if ($resultunit->getBaseUnit() == $unit->getBaseUnit()) {
493 return false;
494 }
495 }
496 if ($resultunit->getBaseUnit()) {
497 if ($resultunit->getBaseUnit() == $unit->getId()) {
498 return false;
499 }
500 }
501 if ($unit->getBaseUnit()) {
502 if ($unit->getBaseUnit() == $resultunit->getId()) {
503 return false;
504 }
505 }
506 }
507 }
508 }
509 return true;
510 }
511
516 public function isComplete()
517 {
518 if (($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0)) {
519 return true;
520 } else {
521 return false;
522 }
523 }
524
529 public function saveToDb($original_id = "")
530 {
531 global $DIC;
532 $ilDB = $DIC['ilDB'];
533
535 // save variables
536 $affectedRows = $ilDB->manipulateF(
537 "
538 DELETE FROM il_qpl_qst_fq_var
539 WHERE question_fi = %s",
540 array("integer"),
541 array($this->getId())
542 );
543
544 foreach ($this->variables as $variable) {
545 $next_id = $ilDB->nextId('il_qpl_qst_fq_var');
546 $ilDB->insert(
547 'il_qpl_qst_fq_var',
548 array(
549 'variable_id' => array('integer', $next_id),
550 'question_fi' => array('integer', $this->getId()),
551 'variable' => array('text', $variable->getVariable()),
552 'range_min' => array('float', ((strlen($variable->getRangeMin())) ? $variable->getRangeMin() : 0.0)),
553 'range_max' => array('float', ((strlen($variable->getRangeMax())) ? $variable->getRangeMax() : 0.0)),
554 'unit_fi' => array('integer', (is_object($variable->getUnit()) ? (int) $variable->getUnit()->getId() : 0)),
555 'varprecision' => array('integer', (int) $variable->getPrecision()),
556 'intprecision' => array('integer', (int) $variable->getIntprecision()),
557 'range_min_txt' => array('text', $variable->getRangeMinTxt()),
558 'range_max_txt' => array('text', $variable->getRangeMaxTxt())
559 )
560 );
561 }
562 // save results
563 $affectedRows = $ilDB->manipulateF(
564 "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
565 array("integer"),
566 array($this->getId())
567 );
568
569 foreach ($this->results as $result) {
570 $next_id = $ilDB->nextId('il_qpl_qst_fq_res');
571 if (is_object($result->getUnit())) {
572 $tmp_result_unit = $result->getUnit()->getId();
573 } else {
574 $tmp_result_unit = null;
575 }
576
577 $formula = str_replace(",", ".", $result->getFormula());
578
579 $ilDB->insert("il_qpl_qst_fq_res", array(
580 "result_id" => array("integer", $next_id),
581 "question_fi" => array("integer", $this->getId()),
582 "result" => array("text", $result->getResult()),
583 "range_min" => array("float", ((strlen($result->getRangeMin())) ? $result->getRangeMin() : 0)),
584 "range_max" => array("float", ((strlen($result->getRangeMax())) ? $result->getRangeMax() : 0)),
585 "tolerance" => array("float", ((strlen($result->getTolerance())) ? $result->getTolerance() : 0)),
586 "unit_fi" => array("integer", (int) $tmp_result_unit),
587 "formula" => array("clob", $formula),
588 "resprecision" => array("integer", $result->getPrecision()),
589 "rating_simple" => array("integer", ($result->getRatingSimple()) ? 1 : 0),
590 "rating_sign" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingSign()),
591 "rating_value" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingValue()),
592 "rating_unit" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingUnit()),
593 "points" => array("float", $result->getPoints()),
594 "result_type" => array('integer', (int) $result->getResultType()),
595 "range_min_txt" => array("text", $result->getRangeMinTxt()),
596 "range_max_txt" => array("text", $result->getRangeMaxTxt())
597
598 ));
599 }
600 // save result units
601 $affectedRows = $ilDB->manipulateF(
602 "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
603 array("integer"),
604 array($this->getId())
605 );
606 foreach ($this->results as $result) {
607 foreach ($this->getResultUnits($result) as $unit) {
608 $next_id = $ilDB->nextId('il_qpl_qst_fq_res_unit');
609 $affectedRows = $ilDB->manipulateF(
610 "INSERT INTO il_qpl_qst_fq_res_unit (result_unit_id, question_fi, result, unit_fi) VALUES (%s, %s, %s, %s)",
611 array('integer', 'integer', 'text', 'integer'),
612 array(
613 $next_id,
614 $this->getId(),
615 $result->getResult(),
616 $unit->getId()
617 )
618 );
619 }
620 }
621
622 parent::saveToDb();
623 }
624
629 public function loadFromDb($question_id)
630 {
631 global $DIC;
632 $ilDB = $DIC['ilDB'];
633
634 $result = $ilDB->queryF(
635 "SELECT qpl_questions.* FROM qpl_questions WHERE question_id = %s",
636 array('integer'),
637 array($question_id)
638 );
639 if ($result->numRows() == 1) {
640 $data = $ilDB->fetchAssoc($result);
641 $this->setId($question_id);
642 $this->setTitle($data["title"]);
643 $this->setComment($data["description"]);
644 $this->setSuggestedSolution($data["solution_hint"]);
645 $this->setPoints($data['points']);
646 $this->setOriginalId($data["original_id"]);
647 $this->setObjId($data["obj_fi"]);
648 $this->setAuthor($data["author"]);
649 $this->setOwner($data["owner"]);
650
651 try {
652 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
653 } catch (ilTestQuestionPoolException $e) {
654 }
655
656 $this->unitrepository = new ilUnitConfigurationRepository($question_id);
657
658 include_once("./Services/RTE/classes/class.ilRTE.php");
659 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
660 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
661
662 // load variables
663 $result = $ilDB->queryF(
664 "SELECT * FROM il_qpl_qst_fq_var WHERE question_fi = %s",
665 array('integer'),
666 array($question_id)
667 );
668 if ($result->numRows() > 0) {
669 while ($data = $ilDB->fetchAssoc($result)) {
670 $varObj = new assFormulaQuestionVariable($data["variable"], $data["range_min"], $data["range_max"], $this->getUnitrepository()->getUnit($data["unit_fi"]), $data["varprecision"], $data["intprecision"]);
671 $varObj->setRangeMinTxt($data['range_min_txt']);
672 $varObj->setRangeMaxTxt($data['range_max_txt']);
673 $this->addVariable($varObj);
674 }
675 }
676 // load results
677 $result = $ilDB->queryF(
678 "SELECT * FROM il_qpl_qst_fq_res WHERE question_fi = %s",
679 array('integer'),
680 array($question_id)
681 );
682 if ($result->numRows() > 0) {
683 while ($data = $ilDB->fetchAssoc($result)) {
684 $resObj = new assFormulaQuestionResult($data["result"], $data["range_min"], $data["range_max"], $data["tolerance"], $this->getUnitrepository()->getUnit($data["unit_fi"]), $data["formula"], $data["points"], $data["resprecision"], $data["rating_simple"], $data["rating_sign"], $data["rating_value"], $data["rating_unit"]);
685 $resObj->setResultType($data['result_type']);
686 $resObj->setRangeMinTxt($data['range_min_txt']);
687 $resObj->setRangeMaxTxt($data['range_max_txt']);
688 $this->addResult($resObj);
689 }
690 }
691
692 // load result units
693 $result = $ilDB->queryF(
694 "SELECT * FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
695 array('integer'),
696 array($question_id)
697 );
698 if ($result->numRows() > 0) {
699 while ($data = $ilDB->fetchAssoc($result)) {
700 $unit = $this->getUnitrepository()->getUnit($data["unit_fi"]);
701 $resObj = $this->getResult($data["result"]);
702 $this->addResultUnit($resObj, $unit);
703 }
704 }
705 }
706 parent::loadFromDb($question_id);
707 }
708
713 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
714 {
715 if ($this->id <= 0) {
716 // The question has not been saved. It cannot be duplicated
717 return;
718 }
719 // duplicate the question in database
720 $this_id = $this->getId();
721 $thisObjId = $this->getObjId();
722
723 $clone = $this;
724 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
726 $clone->id = -1;
727
728 if ((int) $testObjId > 0) {
729 $clone->setObjId($testObjId);
730 }
731
732 if ($title) {
733 $clone->setTitle($title);
734 }
735
736 if ($author) {
737 $clone->setAuthor($author);
738 }
739 if ($owner) {
740 $clone->setOwner($owner);
741 }
742
743 if ($for_test) {
744 $clone->saveToDb($original_id);
745 } else {
746 $clone->saveToDb();
747 }
748
749 $clone->unitrepository->cloneUnits($this_id, $clone->getId());
750
751 // copy question page content
752 $clone->copyPageOfQuestion($this_id);
753 // copy XHTML media objects
754 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
755 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
756
757 return $clone->id;
758 }
759
764 public function copyObject($target_questionpool_id, $title = "")
765 {
766 if ($this->id <= 0) {
767 // The question has not been saved. It cannot be duplicated
768 return;
769 }
770 // duplicate the question in database
771 $clone = $this;
772 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
774 $clone->id = -1;
775 $source_questionpool_id = $this->getObjId();
776 $clone->setObjId($target_questionpool_id);
777 if ($title) {
778 $clone->setTitle($title);
779 }
780 $clone->saveToDb();
781
782 $clone->unitrepository->cloneUnits($original_id, $clone->getId());
783
784 // copy question page content
785 $clone->copyPageOfQuestion($original_id);
786 // copy XHTML media objects
787 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
788
789 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
790
791 return $clone->id;
792 }
793
794 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
795 {
796 if ($this->id <= 0) {
797 // The question has not been saved. It cannot be duplicated
798 return;
799 }
800
801 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
802
803 $sourceQuestionId = $this->id;
804 $sourceParentId = $this->getObjId();
805
806 // duplicate the question in database
807 $clone = $this;
808 $clone->id = -1;
809
810 $clone->setObjId($targetParentId);
811
812 if ($targetQuestionTitle) {
813 $clone->setTitle($targetQuestionTitle);
814 }
815
816 $clone->saveToDb();
817 // copy question page content
818 $clone->copyPageOfQuestion($sourceQuestionId);
819 // copy XHTML media objects
820 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
821
822 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
823
824 return $clone->id;
825 }
826
831 public function getMaximumPoints()
832 {
833 $points = 0;
834 foreach ($this->results as $result) {
835 $points += $result->getPoints();
836 }
837 return $points;
838 }
839
848 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
849 {
850 if (is_null($pass)) {
851 $pass = $this->getSolutionMaxPass($active_id);
852 }
853 $solutions = &$this->getSolutionValues($active_id, $pass, $authorizedSolution);
854 $user_solution = array();
855 foreach ($solutions as $idx => $solution_value) {
856 if (preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches)) {
857 $user_solution[$matches[1]] = $solution_value["value2"];
858 $varObj = $this->getVariable($solution_value["value1"]);
859 $varObj->setValue($solution_value["value2"]);
860 } elseif (preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches)) {
861 if (!array_key_exists($matches[1], $user_solution)) {
862 $user_solution[$matches[1]] = array();
863 }
864 $user_solution[$matches[1]]["value"] = $solution_value["value2"];
865 } elseif (preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches)) {
866 if (!array_key_exists($matches[1], $user_solution)) {
867 $user_solution[$matches[1]] = array();
868 }
869 $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
870 }
871 }
872 //vd($this->getResults());
873 $points = 0;
874 foreach ($this->getResults() as $result) {
875 //vd($user_solution[$result->getResult()]["value"]);
876 $points += $result->getReachedPoints($this->getVariables(), $this->getResults(), $user_solution[$result->getResult()]["value"], $user_solution[$result->getResult()]["unit"], $this->unitrepository->getUnits());
877 }
878
879 return $points;
880 }
881
883 {
884 $user_solution = $previewSession->getParticipantsSolution();
885
886 $points = 0;
887 foreach ($this->getResults() as $result) {
888 $v = isset($user_solution[$result->getResult()]) ? $user_solution[$result->getResult()] : null;
889 $u = isset($user_solution[$result->getResult() . '_unit']) ? $user_solution[$result->getResult() . '_unit'] : null;
890
891 $points += $result->getReachedPoints(
892 $this->getVariables(),
893 $this->getResults(),
894 $v,
895 $u,
896 $this->unitrepository->getUnits()
897 );
898 }
899
900 $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
901
902 return $this->ensureNonNegativePoints($reachedPoints);
903 }
904
905 protected function isValidSolutionResultValue($submittedValue)
906 {
907 $submittedValue = str_replace(',', '.', $submittedValue);
908
909 if (is_numeric($submittedValue)) {
910 return true;
911 }
912
913 if (preg_match('/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
914 return true;
915 }
916
917 return false;
918 }
919
927 public function saveWorkingData($active_id, $pass = null, $authorized = true)
928 {
929 global $DIC;
930 $ilDB = $DIC['ilDB'];
931
932 if (is_null($pass)) {
933 include_once "./Modules/Test/classes/class.ilObjTest.php";
934 $pass = ilObjTest::_getPass($active_id);
935 }
936
937 $entered_values = false;
938
939 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $ilDB, $active_id, $pass, $authorized) {
940 $solutionSubmit = $this->getSolutionSubmit();
941 foreach ($solutionSubmit as $key => $value) {
942 $matches = null;
943 if (preg_match("/^result_(\\\$r\\d+)$/", $key, $matches)) {
944 if (strlen($value)) {
945 $entered_values = true;
946 }
947
948 $queryResult = "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND authorized = %s AND " . $ilDB->like('value1', 'clob', $matches[1]);
949
950 if ($this->getStep() !== null) {
951 $queryResult .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
952 }
953
954 $result = $ilDB->queryF(
955 $queryResult,
956 array('integer', 'integer', 'integer', 'integer'),
957 array($active_id, $pass, $this->getId(), (int) $authorized)
958 );
959 if ($result->numRows()) {
960 while ($row = $ilDB->fetchAssoc($result)) {
961 $ilDB->manipulateF(
962 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
963 array('integer', 'integer'),
964 array($row['solution_id'], (int) $authorized)
965 );
966 }
967 }
968
969 $this->saveCurrentSolution($active_id, $pass, $matches[1], str_replace(",", ".", $value), $authorized);
970 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches)) {
971 $queryResultUnit = "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND authorized = %s AND " . $ilDB->like('value1', 'clob', $matches[1] . "_unit");
972
973 if ($this->getStep() !== null) {
974 $queryResultUnit .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
975 }
976
977 $result = $ilDB->queryF(
978 $queryResultUnit,
979 array('integer', 'integer', 'integer', 'integer'),
980 array($active_id, $pass, $this->getId(), (int) $authorized)
981 );
982 if ($result->numRows()) {
983 while ($row = $ilDB->fetchAssoc($result)) {
984 $ilDB->manipulateF(
985 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
986 array('integer', 'integer'),
987 array($row['solution_id'], (int) $authorized)
988 );
989 }
990 }
991
992 $this->saveCurrentSolution($active_id, $pass, $matches[1] . "_unit", $value, $authorized);
993 }
994 }
995 });
996
997 if ($entered_values) {
998 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1000 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1001 }
1002 } else {
1003 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1005 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1006 }
1007 }
1008
1009 return true;
1010 }
1011
1012 // fau: testNav - overridden function lookupForExistingSolutions (specific for formula question: don't lookup variables)
1019 public function lookupForExistingSolutions($activeId, $pass)
1020 {
1021 global $DIC;
1022 $ilDB = $DIC['ilDB'];
1023
1024 $return = array(
1025 'authorized' => false,
1026 'intermediate' => false
1027 );
1028
1029 $query = "
1030 SELECT authorized, COUNT(*) cnt
1031 FROM tst_solutions
1032 WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
1033 AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
1034 AND pass = " . $ilDB->quote($pass, 'integer') . "
1035 AND value1 like '\$r%'
1036 AND value2 is not null
1037 AND value2 <> ''
1038 ";
1039
1040 if ($this->getStep() !== null) {
1041 $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
1042 }
1043
1044 $query .= "
1045 GROUP BY authorized
1046 ";
1047
1048 $result = $ilDB->query($query);
1049
1050 while ($row = $ilDB->fetchAssoc($result)) {
1051 if ($row['authorized']) {
1052 $return['authorized'] = $row['cnt'] > 0;
1053 } else {
1054 $return['intermediate'] = $row['cnt'] > 0;
1055 }
1056 }
1057 return $return;
1058 }
1059 // fau.
1060
1061 // fau: testNav - Remove an existing solution (specific for formula question: don't delete variables)
1068 public function removeExistingSolutions($activeId, $pass)
1069 {
1070 global $DIC;
1071 $ilDB = $DIC['ilDB'];
1072
1073 $query = "
1074 DELETE FROM tst_solutions
1075 WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
1076 AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
1077 AND pass = " . $ilDB->quote($pass, 'integer') . "
1078 AND value1 like '\$r%'
1079 ";
1080
1081 if ($this->getStep() !== null) {
1082 $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
1083 }
1084
1085 return $ilDB->manipulate($query);
1086 }
1087 // fau.
1088
1089 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1090 {
1091 $userSolution = $previewSession->getParticipantsSolution();
1092
1093 foreach ($this->getSolutionSubmit() as $key => $val) {
1094 $matches = null;
1095
1096 if (preg_match("/^result_(\\\$r\\d+)$/", $key, $matches)) {
1097 $userSolution[$matches[1]] = $val;
1098 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches)) {
1099 $userSolution[$matches[1] . "_unit"] = $val;
1100 }
1101 }
1102
1103 $previewSession->setParticipantsSolution($userSolution);
1104 }
1105
1110 public function getQuestionType()
1111 {
1112 return "assFormulaQuestion";
1113 }
1114
1119 public function getAdditionalTableName()
1120 {
1121 return "";
1122 }
1123
1128 public function getAnswerTableName()
1129 {
1130 return "";
1131 }
1132
1138 public function deleteAnswers($question_id)
1139 {
1140 global $DIC;
1141 $ilDB = $DIC['ilDB'];
1142
1143 $affectedRows = $ilDB->manipulateF(
1144 "DELETE FROM il_qpl_qst_fq_var WHERE question_fi = %s",
1145 array('integer'),
1146 array($question_id)
1147 );
1148
1149 $affectedRows = $ilDB->manipulateF(
1150 "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
1151 array('integer'),
1152 array($question_id)
1153 );
1154
1155 $affectedRows = $ilDB->manipulateF(
1156 "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
1157 array('integer'),
1158 array($question_id)
1159 );
1160
1161 $affectedRows = $ilDB->manipulateF(
1162 "DELETE FROM il_qpl_qst_fq_ucat WHERE question_fi = %s",
1163 array('integer'),
1164 array($question_id)
1165 );
1166
1167 $affectedRows = $ilDB->manipulateF(
1168 "DELETE FROM il_qpl_qst_fq_unit WHERE question_fi = %s",
1169 array('integer'),
1170 array($question_id)
1171 );
1172 }
1173
1179 {
1180 $text = parent::getRTETextWithMediaObjects();
1181 return $text;
1182 }
1183
1187 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1188 {
1189 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1190
1191 $solution = $this->getSolutionValues($active_id, $pass);
1192
1193 $i = 1;
1194 foreach ($solution as $solutionvalue) {
1195 $worksheet->setCell($startrow + $i, 0, $solutionvalue["value1"]);
1196 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
1197 if (strpos($solutionvalue["value1"], "_unit")) {
1198 $unit = $this->getUnitrepository()->getUnit($solutionvalue["value2"]);
1199 if (is_object($unit)) {
1200 $worksheet->setCell($startrow + $i, 1, $unit->getUnit());
1201 }
1202 } else {
1203 $worksheet->setCell($startrow + $i, 1, $solutionvalue["value2"]);
1204 }
1205 if (preg_match("/(\\\$v\\d+)/", $solutionvalue["value1"], $matches)) {
1206 $var = $this->getVariable($solutionvalue["value1"]);
1207 if (is_object($var) && (is_object($var->getUnit()))) {
1208 $worksheet->setCell($startrow + $i, 2, $var->getUnit()->getUnit());
1209 }
1210 }
1211 $i++;
1212 }
1213
1214 return $startrow + $i + 1;
1215 }
1216
1222 public function getBestSolution($solutions)
1223 {
1224 $user_solution = array();
1225
1226 foreach ($solutions as $idx => $solution_value) {
1227 if (preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches)) {
1228 $user_solution[$matches[1]] = $solution_value["value2"];
1229 $varObj = $this->getVariable($matches[1]);
1230 $varObj->setValue($solution_value["value2"]);
1231 } elseif (preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches)) {
1232 if (!array_key_exists($matches[1], $user_solution)) {
1233 $user_solution[$matches[1]] = array();
1234 }
1235 $user_solution[$matches[1]]["value"] = $solution_value["value2"];
1236 } elseif (preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches)) {
1237 if (!array_key_exists($matches[1], $user_solution)) {
1238 $user_solution[$matches[1]] = array();
1239 }
1240 $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
1241 }
1242 }
1243 foreach ($this->getResults() as $result) {
1244 $resVal = $result->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), false);
1245
1246 if (is_object($result->getUnit())) {
1247 $user_solution[$result->getResult()]["unit"] = $result->getUnit()->getId();
1248 $user_solution[$result->getResult()]["value"] = $resVal;
1249 } elseif ($result->getUnit() == null) {
1250 $unit_factor = 1;
1251 // there is no fix result_unit, any "available unit" is accepted
1252
1253 $available_units = $result->getAvailableResultUnits(parent::getId());
1254 $result_name = $result->getResult();
1255
1256 if ($available_units[$result_name] != null) {
1257 $check_unit = in_array($user_solution[$result_name]['unit'], $available_units[$result_name]);
1258 }
1259
1260 if ($check_unit == true) {
1261 //get unit-factor
1262 $unit_factor = assFormulaQuestionUnit::lookupUnitFactor($user_solution[$result_name]['unit']);
1263 }
1264
1265 try {
1266 $user_solution[$result->getResult()]["value"] = ilMath::_div($resVal, $unit_factor, 55);
1267 } catch (ilMathDivisionByZeroException $ex) {
1268 $user_solution[$result->getResult()]["value"] = 0;
1269 }
1270 }
1272 || $result->getResultType() == assFormulaQuestionResult::RESULT_FRAC) {
1274 if (is_array($value)) {
1275 $user_solution[$result->getResult()]["value"] = $value[0];
1276 $user_solution[$result->getResult()]["frac_helper"] = $value[1];
1277 } else {
1278 $user_solution[$result->getResult()]["value"] = $value;
1279 $user_solution[$result->getResult()]["frac_helper"] = null;
1280 }
1281 } else {
1282 $user_solution[$result->getResult()]["value"] = round($user_solution[$result->getResult()]["value"], $result->getPrecision());
1283 /*
1284 $user_solution[$result->getResult()]["value"] = ilMath::_div(
1285 $user_solution[$result->getResult()]["value"],
1286 1,
1287 $result->getPrecision()
1288 );
1289 */
1290 }
1291 }
1292 return $user_solution;
1293 }
1294
1295 public function setId($id = -1)
1296 {
1297 parent::setId($id);
1298 $this->unitrepository->setConsumerId($this->getId());
1299 }
1300
1304 public function __get($value)
1305 {
1306 switch ($value) {
1307 case "resultunits":
1308 return $this->resultunits;
1309 break;
1310 default:
1311 return parent::__get($value);
1312 break;
1313 }
1314 }
1315
1320 {
1321 $this->unitrepository = $unitrepository;
1322 }
1323
1327 public function getUnitrepository()
1328 {
1329 return $this->unitrepository;
1330 }
1331
1335 protected function getSolutionSubmit()
1336 {
1337 $solutionSubmit = array();
1338 foreach ($_POST as $k => $v) {
1339 if (preg_match("/^result_(\\\$r\\d+)$/", $k)) {
1340 $solutionSubmit[$k] = $v;
1341 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $k)) {
1342 $solutionSubmit[$k] = $v;
1343 }
1344 }
1345 return $solutionSubmit;
1346 }
1347
1348 public function validateSolutionSubmit()
1349 {
1350 foreach ($this->getSolutionSubmit() as $key => $value) {
1351 if (preg_match("/^result_(\\\$r\\d+)$/", $key)) {
1352 if (strlen($value) && !$this->isValidSolutionResultValue($value)) {
1353 ilUtil::sendFailure($this->lng->txt("err_no_numeric_value"), true);
1354 return false;
1355 }
1356 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key)) {
1357 continue;
1358 }
1359 }
1360
1361 return true;
1362 }
1363
1372 public function getOperators($expression)
1373 {
1374 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1376 }
1377
1382 public function getExpressionTypes()
1383 {
1384 return array(
1388 );
1389 }
1390
1399 public function getUserQuestionResult($active_id, $pass)
1400 {
1402 global $DIC;
1403 $ilDB = $DIC['ilDB'];
1404 $result = new ilUserQuestionResult($this, $active_id, $pass);
1405
1406 $maxStep = $this->lookupMaxStep($active_id, $pass);
1407
1408 if ($maxStep !== null) {
1409 $data = $ilDB->queryF(
1410 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1411 array("integer", "integer", "integer",'integer'),
1412 array($active_id, $pass, $this->getId(), $maxStep)
1413 );
1414 } else {
1415 $data = $ilDB->queryF(
1416 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1417 array("integer", "integer", "integer"),
1418 array($active_id, $pass, $this->getId())
1419 );
1420 }
1421
1422 while ($row = $ilDB->fetchAssoc($data)) {
1423 if (strstr($row["value1"], '$r') && $row["value2"] != null) {
1424 $result->addKeyValue(str_replace('$r', "", $row["value1"]), $row["value2"]);
1425 }
1426 }
1427
1428 $points = $this->calculateReachedPoints($active_id, $pass);
1429 $max_points = $this->getMaximumPoints();
1430
1431 $result->setReachedPercentage(($points / $max_points) * 100);
1432
1433 return $result;
1434 }
1435
1444 public function getAvailableAnswerOptions($index = null)
1445 {
1446 if ($index !== null) {
1447 return $this->getResult('$r' . ($index + 1));
1448 } else {
1449 return $this->getResults();
1450 }
1451 }
1452}
$result
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
static convertDecimalToCoprimeFraction($decimal_value, $tolerance=1.e-9)
Class for single choice questions assFormulaQuestion is a class for single choice questions.
getBestSolution($solutions)
Returns the best solution for a given pass of a participant.
getQuestionType()
Returns the question type of the question.
substituteVariables(array $userdata, $graphicalOutput=false, $forsolution=false, $result_output=false)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
setUnitrepository($unitrepository)
removeExistingSolutions($activeId, $pass)
Remove an existing solution without removing the variables.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
canUseAdvancedRating($result)
Check if advanced rating can be used for a result.
hasResultUnit($result, $unit_id)
isValidSolutionResultValue($submittedValue)
addResultUnits($result, $unit_ids)
setId($id=-1)
Sets the id of the assQuestion object.
getExpressionTypes()
Get all available expression types for a specific question.
__get($value)
Object getter.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getOperators($expression)
Get all available operations for a specific question.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
copyObject($target_questionpool_id, $title="")
Copies an assFormulaQuestion object @access public.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
lookupForExistingSolutions($activeId, $pass)
Lookup if an authorized or intermediate solution exists.
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
loadFromDb($question_id)
Loads a assFormulaQuestion object from a database.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFormulaQuestion @access public.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question The points are calculated from the g...
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
saveToDb($original_id="")
Saves a assFormulaQuestion object to a database @access public.
hasRequiredVariableSolutionValues(array $userSolution)
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFormulaQuestion constructor The constructor takes possible arguments an creates an instance of the...
deleteAnswers($question_id)
Deletes datasets from answers tables.
getAnswerTableName()
Returns the name of the answer table in the database.
isComplete()
Returns true, if the question is complete for use.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
static _getOriginalId($question_id)
Returns the original id of a question.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
setAuthor($author="")
Sets the authors name of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
setQuestion($question="")
Sets the question string of the question object.
ensureNonNegativePoints($points)
static _div($left_operand, $right_operand, $scale=50)
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
special template class to simplify handling of ITX/PEAR
Class ilUnitConfigurationRepository.
Class ilUserQuestionResult.
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)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
$template
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
Class iQuestionCondition.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
$index
Definition: metadata.php:60
$row
$query
global $DIC
Definition: saml.php:7
global $ilDB
$data
Definition: bench.php:6
$text
Definition: errorreport.php:18