19 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
44 $this->variables = array();
45 $this->results = array();
46 $this->resultunits = array();
53 $this->variables = array();
63 if (array_key_exists($variable, $this->variables)) {
64 return $this->variables[$variable];
71 $this->variables[$variable->getVariable()] = $variable;
76 $this->results = array();
86 if (array_key_exists($result, $this->results)) {
87 return $this->results[$result];
94 $this->results[$result->getResult()] = $result;
99 $this->resultunits[$result->getResult()] = array();
100 if ((!is_object($result)) || (!is_array($unit_ids))) {
103 foreach ($unit_ids as
$id) {
104 if (is_numeric($id) && ($id > 0)) {
112 if (is_object($result) && is_object($unit)) {
114 !is_array($this->resultunits[$result->getResult()])) {
115 $this->resultunits[$result->getResult()] = array();
117 $this->resultunits[$result->getResult()][$unit->getId()] = $unit;
123 if (!isset($this->resultunits[$result->
getResult()])) {
127 $result_units = $this->resultunits[$result->
getResult()];
133 return $result_units;
144 if (array_key_exists($unit_id, $this->resultunits[$result->getResult()])) {
156 if (preg_match_all(
"/(\\\$v\\d+)/ims", $this->
getQuestion(), $matches)) {
157 foreach ($matches[1] as $variable) {
163 if (preg_match_all(
"/(\\\$r\\d+)/ims", $this->
getQuestion(), $rmatches)) {
164 foreach ($rmatches[1] as $result) {
173 if (preg_match_all(
"/(\\\$v\\d+)/ims", $this->
getQuestion(), $matches)) {
174 if ((count(array_unique($matches[1]))) != count($matches[1])) {
183 if (preg_match_all(
"/(\\\$r\\d+)/ims", $this->
getQuestion(), $rmatches)) {
184 if ((count(array_unique($rmatches[1]))) != count($rmatches[1])) {
197 $resObjects = array();
200 if (preg_match_all(
"/(\\\$r\\d+)/ims", $questionText, $matches)) {
201 foreach ($matches[1] as $resultKey) {
202 $resObjects[] = $this->
getResult($resultKey);
215 $varObjects = array();
218 if (preg_match_all(
"/(\\\$v\\d+)/ims", $questionText, $matches)) {
219 foreach ($matches[1] as $variableKey) {
234 if (!isset($userSolution[$varObj->getVariable()])) {
238 if (!strlen($userSolution[$varObj->getVariable()])) {
250 $question_id = $this->
getId();
251 $values = $this->pass_presented_variables_repo->getFor(
256 if (is_null($values)) {
258 $this->pass_presented_variables_repo->store(
274 $variableSolutionValues = array();
277 $variableSolutionValues[$varObj->getVariable()] = $varObj->getValue();
280 return $variableSolutionValues;
283 public function saveCurrentSolution(
int $active_id,
int $pass, $value1, $value2,
bool $authorized =
true, $tstamp = 0):
int 286 foreach ($init_solution_vars as $val1 => $val2) {
287 $this->db->manipulateF(
288 "DELETE FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s AND value1 = %s",
289 [
'integer',
'integer',
'integer',
'text'],
290 [$active_id, $this->
getId(), $pass, $val1]
292 parent::saveCurrentSolution($active_id, $pass, $val1, $val2, $authorized);
294 return parent::saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized, $tstamp);
302 public function substituteVariables(array $userdata,
bool $graphicalOutput =
false,
bool $forsolution =
false,
bool $result_output =
false, array $correctness_icons = [])
304 if ((count($this->results) == 0) && (count($this->variables) == 0)) {
311 if (isset($userdata[$varObj->getVariable()]) && strlen($userdata[$varObj->getVariable()])) {
312 $varObj->setValue($userdata[$varObj->getVariable()]);
315 $unit = (is_object($varObj->getUnit())) ? $varObj->getUnit()->getUnit() :
"";
318 if ($varObj->getValue() !== null) {
319 $val = (strlen($varObj->getValue()) > 8) ? strtoupper(sprintf(
"%e", $varObj->getValue())) : $varObj->getValue();
322 $text = preg_replace(
"/\\$" . substr($varObj->getVariable(), 1) .
"(?![0-9]+)/", $val .
" " . $unit .
"\\1", $text);
327 if (preg_match_all(
"/(\\\$r\\d+)/ims", $this->
getQuestion(), $rmatches)) {
328 foreach ($rmatches[1] as $result) {
332 $userdata[$result][
'result_type'] = $resObj->getResultType();
340 if (is_array($userdata) &&
341 isset($userdata[$result]) &&
342 isset($userdata[$result][
"value"])) {
344 } elseif ($forsolution) {
346 if (!is_array($userdata)) {
348 $value = sprintf(
"%." . $resObj->getPrecision() .
"f", $value);
353 if (is_array($value)) {
354 $frac_helper = $value[1];
366 if (count($result_units) > 0) {
368 if (is_array($userdata)) {
369 foreach ($result_units as $unit) {
370 if (isset($userdata[$result][
"unit"]) && $userdata[$result][
"unit"] == $unit->getId()) {
371 $units = $unit->getUnit();
375 if ($resObj->getUnit()) {
376 $units = $resObj->getUnit()->getUnit();
380 $units =
'<select name="result_' . $result .
'_unit">';
381 $units .=
'<option value="-1">' . $this->
lng->txt(
"select_unit") .
'</option>';
382 foreach ($result_units as $unit) {
383 $units .=
'<option value="' . $unit->getId() .
'"';
384 if (array_key_exists($result, $userdata) &&
385 is_array($userdata[$result]) &&
386 array_key_exists(
'unit', $userdata[$result])) {
387 if ($userdata[$result][
"unit"] == $unit->getId()) {
388 $units .=
' selected="selected"';
391 $units .=
'>' . $unit->getUnit() .
'</option>';
393 $units .=
'</select>';
398 switch ($resObj->getResultType()) {
400 $units .=
' ' . $this->
lng->txt(
'expected_result_type') .
': ' . $this->
lng->txt(
'result_dec');
403 if ($frac_helper !==
'') {
404 $units .=
' ≈ ' . $frac_helper .
', ';
405 } elseif (is_array($userdata) &&
406 array_key_exists($result, $userdata) &&
407 array_key_exists(
'frac_helper', $userdata[$result]) &&
408 is_string($userdata[$result][
"frac_helper"])) {
409 if (!preg_match(
'-/-', $value)) {
410 $units .=
' ≈ ' . $userdata[$result][
"frac_helper"] .
', ';
413 $units .=
' ' . $this->
lng->txt(
'expected_result_type') .
': ' . $this->
lng->txt(
'result_frac');
416 if ($frac_helper !==
'') {
417 $units .=
' ≈ ' . $frac_helper .
', ';
418 } elseif (is_array($userdata) && isset($userdata[$result]) && isset($userdata[$result][
"frac_helper"]) && $userdata[$result][
"frac_helper"] !==
'') {
419 if (!preg_match(
'-/-', $value)) {
420 $units .=
' ≈ ' . $userdata[$result][
"frac_helper"] .
', ';
423 $units .=
' ' . $this->
lng->txt(
'expected_result_type') .
': ' . $this->
lng->txt(
'result_co_frac');
429 if ($graphicalOutput) {
432 if (is_array($userdata) && is_array($userdata[$result])) {
433 if (isset($userdata[$result][
"unit"]) && $userdata[$result][
"unit"] > 0) {
437 if (isset($userdata[$result][
"value"])) {
438 $user_value = $userdata[$result][
"value"];
442 $template =
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output_solution_image.html",
true,
true,
'Modules/TestQuestionPool');
444 $correctness_icon = $correctness_icons[
'not_correct'];
445 if ($resObj->isCorrect($this->getVariables(), $this->
getResults(), $user_value, $resunit)) {
446 $correctness_icon = $correctness_icons[
'correct'];
448 $template->setCurrentBlock(
"icon_ok");
449 $template->setVariable(
"ICON_OK", $correctness_icon);
450 $template->parseCurrentBlock();
452 $checkSign = $template->get();
455 if ($result_output) {
456 $template =
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output_solution_result.html",
true,
true,
'Modules/TestQuestionPool');
458 if (is_array($userdata) &&
459 array_key_exists($resObj->getResult(), $userdata) &&
460 array_key_exists(
'value', $userdata[$resObj->getResult()])) {
461 $found = $resObj->getResultInfo(
464 $userdata[$resObj->getResult()][
"value"],
465 $userdata[$resObj->getResult()][
"unit"] ?? null,
469 $found = $resObj->getResultInfo(
473 is_object($resObj->getUnit()) ? $resObj->getUnit()->getId() : null,
478 if ($resObj->getRatingSimple()) {
480 $resulttext .=
"n/a";
482 $resulttext .= $found[
'points'] .
" " . (($found[
'points'] == 1) ? $this->
lng->txt(
'point') : $this->
lng->txt(
'points'));
485 $resulttext .= $this->
lng->txt(
"rated_sign") .
" " . (($found[
'sign']) ? $found[
'sign'] : 0) .
" " . (($found[
'sign'] == 1) ? $this->
lng->txt(
'point') : $this->
lng->txt(
'points')) .
", ";
486 $resulttext .= $this->
lng->txt(
"rated_value") .
" " . (($found[
'value']) ? $found[
'value'] : 0) .
" " . (($found[
'value'] == 1) ? $this->
lng->txt(
'point') : $this->
lng->txt(
'points')) .
", ";
487 $resulttext .= $this->
lng->txt(
"rated_unit") .
" " . (($found[
'unit']) ? $found[
'unit'] : 0) .
" " . (($found[
'unit'] == 1) ? $this->
lng->txt(
'point') : $this->
lng->txt(
'points'));
491 $template->setVariable(
"RESULT_OUTPUT", $resulttext);
493 $resultOutput = $template->get();
495 $text = preg_replace(
"/\\\$" . substr($result, 1) .
"(?![0-9]+)/", $input .
" " . $units .
" " . $checkSign .
" " . $resultOutput .
" " .
"\\1", $text);
504 return '<span class="ilc_qinput_TextInput solutionbox">' 508 $input =
'<input class="ilc_qinput_TextInput" type="text"';
509 $input .=
'spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off"';
510 $input .=
'name="result_' . $result_key .
'"';
511 $input .=
' value="' . $result_value .
'"/>';
524 $resultunit = $result->getUnit();
526 foreach ($result_units as $unit) {
527 if (is_object($resultunit)) {
528 if ($resultunit->getId() != $unit->getId()) {
529 if ($resultunit->getBaseUnit() && $unit->getBaseUnit()) {
530 if ($resultunit->getBaseUnit() == $unit->getBaseUnit()) {
534 if ($resultunit->getBaseUnit()) {
535 if ($resultunit->getBaseUnit() == $unit->getId()) {
539 if ($unit->getBaseUnit()) {
540 if ($unit->getBaseUnit() == $resultunit->getId()) {
556 if (($this->title) and ($this->author) and ($this->question) and ($this->
getMaximumPoints() > 0)) {
578 $affectedRows =
$ilDB->manipulateF(
580 DELETE FROM il_qpl_qst_fq_var 581 WHERE question_fi = %s",
583 array($this->
getId())
586 foreach ($this->variables as $variable) {
587 $next_id =
$ilDB->nextId(
'il_qpl_qst_fq_var');
591 'variable_id' => array(
'integer', $next_id),
592 'question_fi' => array(
'integer', $this->
getId()),
593 'variable' => array(
'text', $variable->getVariable()),
594 'range_min' => array(
'float', ((strlen($variable->getRangeMin())) ? $variable->getRangeMin() : 0.0)),
595 'range_max' => array(
'float', ((strlen($variable->getRangeMax())) ? $variable->getRangeMax() : 0.0)),
596 'unit_fi' => array(
'integer', (is_object($variable->getUnit()) ? (
int) $variable->getUnit()->getId() : 0)),
597 'varprecision' => array(
'integer', (
int) $variable->getPrecision()),
598 'intprecision' => array(
'integer', (
int) $variable->getIntprecision()),
599 'range_min_txt' => array(
'text', $variable->getRangeMinTxt()),
600 'range_max_txt' => array(
'text', $variable->getRangeMaxTxt())
605 $affectedRows =
$ilDB->manipulateF(
606 "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
608 array($this->
getId())
611 foreach ($this->results as $result) {
612 $next_id =
$ilDB->nextId(
'il_qpl_qst_fq_res');
613 if (is_object($result->getUnit())) {
614 $tmp_result_unit = $result->getUnit()->getId();
616 $tmp_result_unit = null;
620 if ($result->getFormula() !== null) {
621 $formula = str_replace(
",",
".", $result->getFormula());
624 $ilDB->insert(
"il_qpl_qst_fq_res", array(
625 "result_id" => array(
"integer", $next_id),
626 "question_fi" => array(
"integer", $this->
getId()),
627 "result" => array(
"text", $result->getResult()),
628 "range_min" => array(
"float", ((strlen($result->getRangeMin())) ? $result->getRangeMin() : 0)),
629 "range_max" => array(
"float", ((strlen($result->getRangeMax())) ? $result->getRangeMax() : 0)),
630 "tolerance" => array(
"float", ((strlen($result->getTolerance())) ? $result->getTolerance() : 0)),
631 "unit_fi" => array(
"integer", (
int) $tmp_result_unit),
632 "formula" => array(
"clob", $formula),
633 "resprecision" => array(
"integer", $result->getPrecision()),
634 "rating_simple" => array(
"integer", ($result->getRatingSimple()) ? 1 : 0),
635 "rating_sign" => array(
"float", ($result->getRatingSimple()) ? 0 : $result->getRatingSign()),
636 "rating_value" => array(
"float", ($result->getRatingSimple()) ? 0 : $result->getRatingValue()),
637 "rating_unit" => array(
"float", ($result->getRatingSimple()) ? 0 : $result->getRatingUnit()),
638 "points" => array(
"float", $result->getPoints()),
639 "result_type" => array(
'integer', (
int) $result->getResultType()),
640 "range_min_txt" => array(
"text", $result->getRangeMinTxt()),
641 "range_max_txt" => array(
"text", $result->getRangeMaxTxt())
646 $affectedRows =
$ilDB->manipulateF(
647 "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
649 array($this->
getId())
651 foreach ($this->results as $result) {
653 $next_id =
$ilDB->nextId(
'il_qpl_qst_fq_res_unit');
654 $affectedRows =
$ilDB->manipulateF(
655 "INSERT INTO il_qpl_qst_fq_res_unit (result_unit_id, question_fi, result, unit_fi) VALUES (%s, %s, %s, %s)",
656 array(
'integer',
'integer',
'text',
'integer'),
660 $result->getResult(),
677 $ilDB = $DIC[
'ilDB'];
679 $result =
$ilDB->queryF(
680 "SELECT qpl_questions.* FROM qpl_questions WHERE question_id = %s",
684 if ($result->numRows() == 1) {
686 $this->
setId($question_id);
688 $this->
setComment((
string) $data[
"description"]);
711 $result =
$ilDB->queryF(
712 "SELECT * FROM il_qpl_qst_fq_var WHERE question_fi = %s",
716 if ($result->numRows() > 0) {
717 while ($data =
$ilDB->fetchAssoc($result)) {
723 $result =
$ilDB->queryF(
724 "SELECT * FROM il_qpl_qst_fq_res WHERE question_fi = %s",
728 if ($result->numRows() > 0) {
729 while ($data =
$ilDB->fetchAssoc($result)) {
730 $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"]);
731 $resObj->setResultType($data[
'result_type']);
737 $result =
$ilDB->queryF(
738 "SELECT * FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
742 if ($result->numRows() > 0) {
743 while ($data =
$ilDB->fetchAssoc($result)) {
745 $resObj = $this->
getResult($data[
"result"]);
750 parent::loadFromDb($question_id);
759 if ($this->
id <= 0) {
764 $this_id = $this->
getId();
769 $original_id = $this->questioninfo->getOriginalId($this->
id);
772 if ((
int) $testObjId > 0) {
773 $clone->setObjId($testObjId);
793 $clone->unitrepository->cloneUnits($this_id, $clone->getId());
796 $clone->copyPageOfQuestion($this_id);
798 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
799 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
810 if ($this->
getId() <= 0) {
811 throw new RuntimeException(
'The question has not been saved. It cannot be duplicated');
816 $original_id = $this->questioninfo->getOriginalId($this->
id);
818 $source_questionpool_id = $this->
getObjId();
819 $clone->setObjId($target_questionpool_id);
825 $clone->unitrepository->cloneUnits(
$original_id, $clone->getId());
832 $clone->onCopy($source_questionpool_id,
$original_id, $clone->getObjId(), $clone->getId());
839 if ($this->
getId() <= 0) {
840 throw new RuntimeException(
'The question has not been saved. It cannot be duplicated');
844 $sourceParentId = $this->
getObjId();
850 $clone->setObjId($targetParentId);
852 if ($targetQuestionTitle) {
853 $clone->setTitle($targetQuestionTitle);
858 $clone->copyPageOfQuestion($sourceQuestionId);
860 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
862 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
874 foreach ($this->results as $result) {
875 $points += $result->getPoints();
888 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution =
true, $returndetails =
false): float
890 if (is_null($pass)) {
894 $user_solution = array();
895 foreach ($solutions as $solution_value) {
896 if (preg_match(
"/^(\\\$v\\d+)$/", $solution_value[
"value1"], $matches)) {
897 $user_solution[$matches[1]] = $solution_value[
"value2"];
898 $varObj = $this->
getVariable($solution_value[
"value1"]);
899 $varObj->setValue($solution_value[
"value2"]);
900 } elseif (preg_match(
"/^(\\\$r\\d+)$/", $solution_value[
"value1"], $matches)) {
901 if (!array_key_exists($matches[1], $user_solution)) {
902 $user_solution[$matches[1]] = array();
904 $user_solution[$matches[1]][
"value"] = $solution_value[
"value2"];
905 } elseif (preg_match(
"/^(\\\$r\\d+)_unit$/", $solution_value[
"value1"], $matches)) {
906 if (!array_key_exists($matches[1], $user_solution)) {
907 $user_solution[$matches[1]] = array();
909 $user_solution[$matches[1]][
"unit"] = $this->unitrepository->getUnit(
910 $this->
refinery->kindlyTo()->int()->transform($solution_value[
"value2"]),
918 $points += $result->getReachedPoints(
921 $user_solution[$result->getResult()][
"value"] ??
'',
922 $user_solution[$result->getResult()][
"unit"] ?? null,
923 $this->unitrepository->getUnits()
936 $unit_id = $user_solution[$result->getResult() .
'_unit'] ?? null;
937 $points += $result->getReachedPoints(
940 $user_solution[$result->getResult()] ??
'',
941 $unit_id !== null ? $this->unitrepository->getUnit($unit_id) : null,
942 $this->unitrepository->getUnits()
953 $submittedValue = str_replace(
',',
'.', $submittedValue);
955 if (is_numeric($submittedValue)) {
959 if (preg_match(
'/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
976 $ilDB = $DIC[
'ilDB'];
978 if (is_null($pass)) {
982 $entered_values =
false;
984 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function () use (&$entered_values,
$ilDB, $active_id, $pass, $authorized) {
986 foreach ($solutionSubmit as
$key => $value) {
988 if (preg_match(
"/^result_(\\\$r\\d+)$/",
$key, $matches)) {
989 if (strlen($value)) {
990 $entered_values =
true;
993 $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]);
995 if ($this->
getStep() !== null) {
996 $queryResult .=
" AND step = " .
$ilDB->quote((
int) $this->
getStep(),
'integer') .
" ";
999 $result =
$ilDB->queryF(
1001 array(
'integer',
'integer',
'integer',
'integer'),
1002 array($active_id, $pass, $this->
getId(), (
int) $authorized)
1004 if ($result->numRows()) {
1005 while ($row =
$ilDB->fetchAssoc($result)) {
1007 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
1008 array(
'integer',
'integer'),
1009 array($row[
'solution_id'], (
int) $authorized)
1014 $this->
saveCurrentSolution($active_id, $pass, $matches[1], str_replace(
",",
".", $value), $authorized);
1015 } elseif (preg_match(
"/^result_(\\\$r\\d+)_unit$/",
$key, $matches)) {
1016 $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");
1018 if ($this->
getStep() !== null) {
1019 $queryResultUnit .=
" AND step = " .
$ilDB->quote((
int) $this->
getStep(),
'integer') .
" ";
1022 $result =
$ilDB->queryF(
1024 array(
'integer',
'integer',
'integer',
'integer'),
1025 array($active_id, $pass, $this->
getId(), (
int) $authorized)
1027 if ($result->numRows()) {
1028 while ($row =
$ilDB->fetchAssoc($result)) {
1030 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
1031 array(
'integer',
'integer'),
1032 array($row[
'solution_id'], (
int) $authorized)
1037 $this->
saveCurrentSolution($active_id, $pass, $matches[1] .
"_unit", $value, $authorized);
1042 if ($entered_values) {
1046 "log_user_entered_values",
1048 ), $active_id, $this->
getId());
1054 "log_user_not_entered_values",
1056 ), $active_id, $this->
getId());
1073 $ilDB = $DIC[
'ilDB'];
1076 'authorized' =>
false,
1077 'intermediate' =>
false 1081 SELECT authorized, COUNT(*) cnt 1083 WHERE active_fi = " .
$ilDB->quote($activeId,
'integer') .
" 1084 AND question_fi = " .
$ilDB->quote($this->
getId(),
'integer') .
" 1085 AND pass = " .
$ilDB->quote($pass,
'integer') .
" 1086 AND value1 like '\$r%' 1087 AND value2 is not null 1091 if ($this->
getStep() !== null) {
1092 $query .=
" AND step = " .
$ilDB->quote((
int) $this->
getStep(),
'integer') .
" ";
1099 $result =
$ilDB->query($query);
1101 while ($row =
$ilDB->fetchAssoc($result)) {
1102 if ($row[
'authorized']) {
1103 $return[
'authorized'] = $row[
'cnt'] > 0;
1105 $return[
'intermediate'] = $row[
'cnt'] > 0;
1122 $ilDB = $DIC[
'ilDB'];
1125 DELETE FROM tst_solutions 1126 WHERE active_fi = " .
$ilDB->quote($activeId,
'integer') .
" 1127 AND question_fi = " .
$ilDB->quote($this->
getId(),
'integer') .
" 1128 AND pass = " .
$ilDB->quote($pass,
'integer') .
" 1129 AND value1 like '\$r%' 1132 if ($this->
getStep() !== null) {
1133 $query .=
" AND step = " .
$ilDB->quote((
int) $this->
getStep(),
'integer') .
" ";
1136 return $ilDB->manipulate($query);
1147 if (preg_match(
"/^result_(\\\$r\\d+)$/",
$key, $matches)) {
1148 $userSolution[$matches[1]] = $val;
1149 } elseif (preg_match(
"/^result_(\\\$r\\d+)_unit$/",
$key, $matches)) {
1150 $userSolution[$matches[1] .
"_unit"] = $val;
1163 return "assFormulaQuestion";
1192 $ilDB = $DIC[
'ilDB'];
1194 $affectedRows =
$ilDB->manipulateF(
1195 "DELETE FROM il_qpl_qst_fq_var WHERE question_fi = %s",
1200 $affectedRows =
$ilDB->manipulateF(
1201 "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
1206 $affectedRows =
$ilDB->manipulateF(
1207 "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
1212 $affectedRows =
$ilDB->manipulateF(
1213 "DELETE FROM il_qpl_qst_fq_ucat WHERE question_fi = %s",
1218 $affectedRows =
$ilDB->manipulateF(
1219 "DELETE FROM il_qpl_qst_fq_unit WHERE question_fi = %s",
1231 $text = parent::getRTETextWithMediaObjects();
1240 parent::setExportDetailsXLSX($worksheet, $startrow, $col, $active_id, $pass);
1245 foreach ($solution as $solutionvalue) {
1246 $worksheet->
setCell($startrow + $i, $col, $solutionvalue[
"value1"]);
1248 if (strpos($solutionvalue[
"value1"],
"_unit")) {
1250 if (is_object($unit)) {
1251 $worksheet->
setCell($startrow + $i, $col + 2, $unit->getUnit());
1254 $worksheet->
setCell($startrow + $i, $col + 2, $solutionvalue[
"value2"]);
1256 if (preg_match(
"/(\\\$v\\d+)/", $solutionvalue[
"value1"], $matches)) {
1257 $var = $this->
getVariable($solutionvalue[
"value1"]);
1258 if (is_object($var) && (is_object($var->getUnit()))) {
1259 $worksheet->
setCell($startrow + $i, $col + 3, $var->getUnit()->getUnit());
1265 return $startrow + $i + 1;
1275 $user_solution = array();
1277 foreach ($solutions as $idx => $solution_value) {
1278 if (preg_match(
"/^(\\\$v\\d+)$/", $solution_value[
"value1"], $matches)) {
1279 $user_solution[$matches[1]] = $solution_value[
"value2"];
1281 $varObj->setValue($solution_value[
"value2"]);
1282 } elseif (preg_match(
"/^(\\\$r\\d+)$/", $solution_value[
"value1"], $matches)) {
1283 if (!array_key_exists($matches[1], $user_solution)) {
1284 $user_solution[$matches[1]] = array();
1286 $user_solution[$matches[1]][
"value"] = $solution_value[
"value2"];
1287 } elseif (preg_match(
"/^(\\\$r\\d+)_unit$/", $solution_value[
"value1"], $matches)) {
1288 if (!array_key_exists($matches[1], $user_solution)) {
1289 $user_solution[$matches[1]] = array();
1291 $user_solution[$matches[1]][
"unit"] = $solution_value[
"value2"];
1297 if (is_object($result->getUnit())) {
1298 $user_solution[$result->getResult()][
"unit"] = $result->getUnit()->getId();
1299 $user_solution[$result->getResult()][
"value"] = $resVal;
1300 } elseif ($result->getUnit() == null) {
1304 $available_units = $result->getAvailableResultUnits(
parent::getId());
1305 $result_name = $result->getResult();
1307 $check_unit =
false;
1308 if (array_key_exists($result_name, $available_units) &&
1309 $available_units[$result_name] !== null) {
1310 $check_unit = in_array($user_solution[$result_name][
'unit'] ?? null, $available_units[$result_name]);
1313 if ($check_unit ==
true) {
1319 $user_solution[$result->getResult()][
"value"] =
ilMath::_div($resVal, $unit_factor, 55);
1321 $user_solution[$result->getResult()][
"value"] = 0;
1327 if (is_array($value)) {
1328 $user_solution[$result->getResult()][
"value"] = $value[0];
1329 $user_solution[$result->getResult()][
"frac_helper"] = $value[1];
1331 $user_solution[$result->getResult()][
"value"] = $value;
1332 $user_solution[$result->getResult()][
"frac_helper"] = null;
1335 $user_solution[$result->getResult()][
"value"] = round($user_solution[$result->getResult()][
"value"], $result->getPrecision());
1345 return $user_solution;
1351 $this->unitrepository->setConsumerId($this->
getId());
1375 $solutionSubmit = [];
1377 $post = $this->dic->http()->wrapper()->post();
1380 $key =
"result_$index";
1382 $value =
$post->retrieve(
1384 $this->dic->refinery()->kindlyTo()->string()
1387 $solutionSubmit[
$key] = $value;
1390 $value =
$post->retrieve(
1392 $this->dic->refinery()->kindlyTo()->string()
1394 $solutionSubmit[
$key .
"_unit"] = $value;
1397 return $solutionSubmit;
1404 $this->tpl->setOnScreenMessage(
1406 $this->
lng->txt(
"err_no_numeric_value"),
1454 $ilDB = $DIC[
'ilDB'];
1461 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1462 array(
"integer",
"integer",
"integer",
'integer'),
1463 array($active_id, $pass, $this->
getId(), $maxStep)
1467 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1468 array(
"integer",
"integer",
"integer"),
1469 array($active_id, $pass, $this->
getId())
1474 if (strstr($row[
"value1"],
'$r') && $row[
"value2"] != null) {
1475 $result->addKeyValue(str_replace(
'$r',
"", $row[
"value1"]), $row[
"value2"]);
1482 $result->setReachedPercentage((
$points / $max_points) * 100);
1497 if ($index !== null) {
1498 return $this->
getResult(
'$r' . ($index + 1));
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
getSolutionValues($active_id, $pass=null, bool $authorized=true)
Loads solutions of a given user from the database an returns it.
static getInstance($identifier)
const PercentageResultExpression
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _div($left_operand, $right_operand, int $scale=50)
Abstract basic class which is to be extended by the concrete assessment question type classes...
getColumnCoord(int $a_col)
Get column "name" from number.
ensureNonNegativePoints($points)
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...
getParticipantsSolution()
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setComment(string $comment="")
float $points
The maximum available points for the question.
setParticipantsSolution($participantSolution)
setBold(string $a_coords)
Set cell(s) to bold.
static _enabledAssessmentLogging()
purifyAndPrepareTextAreaOutput(string $content)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static logAction(string $logtext, int $active_id, int $question_id)
const NumericResultExpression
Stores random-generated parts of questions in order to present the user with a fixed question during ...
string $question
The question text.
static getOperatorsByExpression($expression)
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
saveQuestionDataToDb(int $original_id=-1)
getSolutionMaxPass(int $active_id)
setOriginalId(?int $original_id)
setTitle(string $title="")
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
setLifecycle(ilAssQuestionLifecycle $lifecycle)
lookupMaxStep(int $active_id, int $pass)
setAuthor(string $author="")
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
static getDraftInstance()
setQuestion(string $question="")
const EmptyAnswerExpression