19 require_once 
'./Modules/Test/classes/inc.AssessmentConstants.php';
    45             $this->
object->loadFromDb(
$id);
    51         $ilTabs->
addTarget(
'units', $this->
ctrl->getLinkTargetByClass(
'ilLocalUnitConfigurationGUI', 
''), 
'', 
'illocalunitconfigurationgui');
    56         if (preg_match(
'/suggestrange_(\$r\d+)/', $cmd, $matches)) {
    62     public function suggestRange(
string $suggest_range_for_result): void
    67         $this->editQuestion(
false, $suggest_range_for_result);
    75         $hasErrors = (!$always) ? $this->editQuestion(
true) : 
false;
    78             $this->
object->setTitle($this->request->string(
'title'));
    79             $this->
object->setAuthor($this->request->string(
'author'));
    80             $this->
object->setComment($this->request->string(
'comment'));
    81             $this->
object->setQuestion($this->request->string(
'question'));
    83             $this->
object->parseQuestionText();
    87             foreach ($this->request->getParsedBody() as 
$key => $value) {
    88                 if (preg_match(
"/^unit_(\\\$v\d+)$/", $key, $matches)) {
    89                     array_push($found_vars, $matches[1]);
    91                 if (preg_match(
"/^unit_(\\\$r\d+)$/", $key, $matches)) {
    92                     array_push($found_results, $matches[1]);
   102             if (!$this->
object->checkForDuplicateResults()) {
   107             foreach ($found_vars as $variable) {
   108                 if ($this->
object->getVariable($variable) != null) {
   111                         str_replace(
',', 
'.', $_POST[
"range_min_{$variable}"]),
   112                         str_replace(
',', 
'.', $_POST[
"range_max_{$variable}"]),
   113                         isset($_POST[
"unit_{$variable}"]) ? $this->
object->getUnitrepository()->getUnit(
   114                             $_POST[
"unit_{$variable}"]
   116                         (
int) $this->request->float(
"precision_{$variable}"),
   117                         (
int) $this->request->float(
"intprecision_{$variable}")
   119                     $this->
object->addVariable($varObj);
   124             $tmp_quest_vars = [];
   125             foreach ($found_results as $result) {
   126                 $tmp_res_match = preg_match_all(
'/([$][v][0-9]*)/', $_POST[
"formula_{$result}"], $form_vars);
   127                 $tmp_form_vars = array_merge($tmp_form_vars, $form_vars[0]);
   129                 $tmp_que_match = preg_match_all(
'/([$][v][0-9]*)/', $_POST[
'question'], $quest_vars);
   130                 $tmp_quest_vars = array_merge($tmp_quest_vars, $quest_vars[0]);
   132             $result_has_undefined_vars = array_diff($tmp_form_vars, $found_vars);
   133             $question_has_unused_vars = array_diff($tmp_quest_vars, $tmp_form_vars);
   135             if (count($result_has_undefined_vars) > 0 || count($question_has_unused_vars) > 0) {
   137                 if (count($result_has_undefined_vars) > 0) {
   138                     $error_message .= $this->
lng->txt(
"res_contains_undef_var") . 
'<br>';
   140                 if (count($question_has_unused_vars) > 0) {
   141                     $error_message .= $this->
lng->txt(
"que_contains_unused_var");
   145                     $this->tpl->setOnScreenMessage(
'failure', $error_message);
   148             foreach ($found_results as $result) {
   149                 if ($this->
object->getResult($result) != null) {
   152                         str_replace(
',', 
'.', $_POST[
"range_min_{$result}"]),
   153                         str_replace(
',', 
'.', $_POST[
"range_max_{$result}"]),
   154                         $this->request->float(
"tolerance_{$result}"),
   155                         isset($_POST[
"unit_{$result}"]) ? $this->
object->getUnitrepository()->getUnit(
   156                             $_POST[
"unit_{$result}"]
   158                         $this->request->string(
"formula_{$result}"),
   159                         $this->request->float(
"points_{$result}"),
   160                         (
int) $this->request->float(
"precision_{$result}"),
   161                         $this->request->int(
"rating_advanced_{$result}") !== 1,
   162                         $this->request->int(
"rating_advanced_{$result}") === 1 ? $this->request->float(
"rating_sign_{$result}") : null,
   163                         $this->request->int(
"rating_advanced_{$result}") === 1 ? $this->request->float(
"rating_value_{$result}") : null,
   164                         $this->request->int(
"rating_advanced_{$result}") === 1 ? $this->request->float(
"rating_unit_{$result}") : null,
   165                         $this->request->int(
"result_type_{$result}")
   167                     $this->
object->addResult($resObj);
   168                     $this->
object->addResultUnits($resObj, $_POST[
"units_{$result}"] ?? []);
   171             if ($checked == 
false) {
   172                 $this->editQuestion();
   189         $question_id = $this->
object->getId();
   191         $ilAssQuestionPreviewSession->setParticipantsSolution([]);
   196         return in_array($this->
ctrl->getCmd(), array(
'save', 
'saveEdit', 
'saveReturn'));
   202     public function editQuestion($checkonly = 
false, 
string $suggest_range_for_result = 
''): 
bool   209         $this->editForm = $form;
   211         $form->setFormAction($this->
ctrl->getFormAction($this));
   213         $form->setMultipart(
false);
   214         $form->setTableWidth(
'100%');
   215         $form->setId(
'assformulaquestion');
   220         $question = $form->getItemByPostVar(
'question');
   221         $question->setInfo($this->
lng->txt(
'fq_question_desc'));
   223         $variables = $this->
object->getVariables();
   224         $categorized_units = $this->
object->getUnitrepository()->getCategorizedUnits();
   225         $result_units = $this->
object->getAllResultUnits();
   229         $new_category = 
false;
   230         foreach ($categorized_units as $item) {
   235                 if ($category_name != $item->getDisplayString()) {
   236                     $new_category = 
true;
   237                     $category_name = $item->getDisplayString();
   241             $unit_options[$item->getId()] = $item->getDisplayString() . ($new_category ? 
' (' . $category_name . 
')' : 
'');
   242             $new_category = 
false;
   245         if (count($variables)) {
   249                 if ($num_v1 > $num_v2) {
   251                 } elseif ($num_v1 < $num_v2) {
   258             foreach ($variables as $variable) {
   263                 $variable_header->setTitle(sprintf($this->
lng->txt(
'variable_x'), $variable->getVariable()));
   265                 $range_min = 
new ilNumberInputGUI($this->
lng->txt(
'range_min'), 
'range_min_' . $variable->getVariable());
   266                 $range_min->allowDecimals(
true);
   267                 $range_min->setSize(3);
   268                 $range_min->setRequired(
true);
   269                 $range_min->setValue($variable->getRangeMin());
   271                 $range_max = 
new ilNumberInputGUI($this->
lng->txt(
'range_max'), 
'range_max_' . $variable->getVariable());
   272                 $range_max->allowDecimals(
true);
   273                 $range_max->setSize(3);
   274                 $range_max->setRequired(
true);
   275                 $range_max->setValue($variable->getRangeMax());
   277                 $units = 
new ilSelectInputGUI($this->
lng->txt(
'unit'), 
'unit_' . $variable->getVariable());
   278                 $units->
setOptions(array(0 => $this->
lng->txt(
'no_selection')) + $unit_options);
   279                 if (is_object($variable->getUnit())) {
   280                     $units->setValue($variable->getUnit()->getId());
   283                 $precision = 
new ilNumberInputGUI($this->
lng->txt(
'precision'), 
'precision_' . $variable->getVariable());
   284                 $precision->setRequired(
true);
   285                 $precision->setSize(3);
   286                 $precision->setMinValue(0);
   287                 $precision->setValue($variable->getPrecision());
   288                 $precision->setInfo($this->
lng->txt(
'fq_precision_info'));
   290                 $intprecision = 
new ilNumberInputGUI($this->
lng->txt(
'intprecision'), 
'intprecision_' . $variable->getVariable());
   291                 $intprecision->setSize(3);
   292                 $intprecision->setMinValue(1);
   293                 $intprecision->setValue($variable->getIntprecision());
   294                 $intprecision->setInfo($this->
lng->txt(
'intprecision_info'));
   296                 $form->addItem($variable_header);
   297                 $form->addItem($range_min);
   298                 $form->addItem($range_max);
   299                 $form->addItem($units);
   300                 $form->addItem($precision);
   301                 $form->addItem($intprecision);
   306         $results = $this->
object->getResults();
   311                 if ($num_r1 > $num_r2) {
   313                 } elseif ($num_r1 < $num_r2) {
   325                 $result_header->setTitle(sprintf($this->
lng->txt(
'result_x'), $result->getResult()));
   327                 $formula = 
new ilTextInputGUI($this->
lng->txt(
'formula'), 
'formula_' . $result->getResult());
   328                 $formula->setInfo($this->
lng->txt(
'fq_formula_desc'));
   329                 $formula->setRequired(
true);
   330                 $formula->setSize(50);
   331                 $formula->setValue($result->getFormula());
   332                 $formula->setSuffix(
' = ' . $result->getResult());
   335                     $suggest_range_for_result !== 
'' &&
   336                     strcmp($suggest_range_for_result, $result->getResult()) == 0 &&
   337                     strlen($result->substituteFormula($variables, 
$results))
   339                     $result->suggestRange($variables, 
$results);
   342                 $range_min = 
new ilNumberInputGUI($this->
lng->txt(
'range_min'), 
'range_min_' . $result->getResult());
   343                 $range_min->allowDecimals(
true);
   344                 $range_min->setSize(3);
   345                 $range_min->setRequired(
true);
   346                 $range_min->setValue($result->getRangeMin());
   348                 $range_max = 
new ilNumberInputGUI($this->
lng->txt(
'range_max'), 
'range_max_' . $result->getResult());
   349                 $range_max->allowDecimals(
true);
   350                 $range_max->setSize(3);
   351                 $range_max->setRequired(
true);
   352                 $range_max->setValue($result->getRangeMax());
   356                 $precision = 
new ilNumberInputGUI($this->
lng->txt(
'precision'), 
'precision_' . $result->getResult());
   357                 $precision->setRequired(
true);
   358                 $precision->setSize(3);
   359                 $precision->setMinValue(0);
   360                 $precision->setInfo($this->
lng->txt(
'fq_precision_info'));
   361                 $precision->setValue($result->getPrecision());
   363                 $tolerance = 
new ilNumberInputGUI($this->
lng->txt(
'tolerance'), 
'tolerance_' . $result->getResult());
   364                 $tolerance->setSize(3);
   365                 $tolerance->setMinValue(0);
   366                 $tolerance->setMaxValue(100);
   367                 $tolerance->allowDecimals(
true);
   368                 $tolerance->setInfo($this->
lng->txt(
'tolerance_info'));
   369                 $tolerance->setValue($result->getTolerance());
   372                 $suggest_range_button->setHtml(
'<input type="submit" class="btn btn-default" name="cmd[suggestrange_' . $result->getResult() . 
']" value="' . $this->
lng->txt(
"suggest_range") . 
'" />');
   374                 $sel_result_units = 
new ilSelectInputGUI($this->
lng->txt(
'unit'), 
'unit_' . $result->getResult());
   375                 $sel_result_units->
setOptions(array(0 => $this->
lng->txt(
'no_selection')) + $unit_options);
   376                 $sel_result_units->setInfo($this->
lng->txt(
'result_unit_info'));
   377                 if (is_object($result->getUnit())) {
   378                     $sel_result_units->setValue($result->getUnit()->getId());
   383                 $mc_result_units->setInfo($this->
lng->txt(
'result_units_info'));
   384                 $selectedvalues = [];
   385                 foreach ($unit_options as $unit_id => 
$txt) {
   386                     if ($this->
hasResultUnit($result, $unit_id, $result_units)) {
   387                         $selectedvalues[] = $unit_id;
   390                 $mc_result_units->setValue($selectedvalues);
   392                 $result_type = 
new ilRadioGroupInputGUI($this->
lng->txt(
'result_type_selection'), 
'result_type_' . $result->getResult());
   396                 $no_type->
setInfo($this->
lng->txt(
'fq_no_restriction_info'));
   399                 $result_dec->
setInfo($this->
lng->txt(
'result_dec_info'));
   402                 $result_frac->
setInfo($this->
lng->txt(
'result_frac_info'));
   404                 $result_co_frac = 
new ilRadioOption($this->
lng->txt(
'result_co_frac'), 
'3');
   405                 $result_co_frac->
setInfo($this->
lng->txt(
'result_co_frac_info'));
   407                 $result_type->addOption($no_type);
   408                 $result_type->addOption($result_dec);
   409                 $result_type->addOption($result_frac);
   410                 $result_type->addOption($result_co_frac);
   411                 $result_type->setValue(strlen($result->getResultType()) ? $result->getResultType() : 0);
   413                 $points = 
new ilNumberInputGUI($this->
lng->txt(
'points'), 
'points_' . $result->getResult());
   414                 $points->allowDecimals(
true);
   415                 $points->setRequired(
true);
   417                 $points->setMinValue(0);
   418                 $points->setValue(strlen($result->getPoints()) ? $result->getPoints() : 1);
   420                 $rating_type = 
new ilCheckboxInputGUI($this->
lng->txt(
'advanced_rating'), 
'rating_advanced_' . $result->getResult());
   421                 $rating_type->setValue(1);
   422                 $rating_type->setInfo($this->
lng->txt(
'advanced_rating_info'));
   426                     if (!$advanced_rating) {
   427                         $rating_type->setDisabled(
true);
   428                         $rating_type->setChecked(
false);
   430                         $rating_type->setChecked(strlen($result->getRatingSimple()) && $result->getRatingSimple() ? false : 
true);
   434                 $sign = 
new ilNumberInputGUI($this->
lng->txt(
'rating_sign'), 
'rating_sign_' . $result->getResult());
   435                 $sign->setRequired(
true);
   437                 $sign->setMinValue(0);
   438                 $sign->setValue($result->getRatingSign());
   439                 $rating_type->addSubItem($sign);
   441                 $value = 
new ilNumberInputGUI($this->
lng->txt(
'rating_value'), 
'rating_value_' . $result->getResult());
   442                 $value->setRequired(
true);
   444                 $value->setMinValue(0);
   445                 $value->setValue($result->getRatingValue());
   446                 $rating_type->addSubItem($value);
   448                 $unit = 
new ilNumberInputGUI($this->
lng->txt(
'rating_unit'), 
'rating_unit_' . $result->getResult());
   449                 $unit->setRequired(
true);
   451                 $unit->setMinValue(0);
   452                 $unit->setValue($result->getRatingUnit());
   453                 $rating_type->addSubItem($unit);
   456                 $rating_type->addSubItem($info_text);
   458                 $form->addItem($result_header);
   459                 $form->addItem($formula);
   460                 $form->addItem($range_min);
   461                 $form->addItem($range_max);
   462                 $form->addItem($suggest_range_button);
   463                 $form->addItem($precision);
   464                 $form->addItem($tolerance);
   465                 $form->addItem($sel_result_units);
   466                 $form->addItem($mc_result_units);
   467                 $form->addItem($result_type);
   468                 $form->addItem($points);
   469                 $form->addItem($rating_type);
   472             $defined_result_vars = [];
   474             $defined_result_res = [];
   488                 $formula = $tmp_result->getFormula() ?? 
'';
   490                 preg_match_all(
"/([$][v][0-9]*)/", $formula, $form_vars);
   491                 preg_match_all(
"/([$][r][0-9]*)/", $formula, $form_res);
   492                 foreach ($form_vars[0] as $res_var) {
   493                     $defined_result_vars[$res_var] = $res_var;
   496                 foreach ($form_res[0] as $res_res) {
   497                     $defined_result_res[$res_res] = $res_res;
   502         $result_has_undefined_vars = [];
   503         $question_has_unused_vars = [];
   504         $result_has_undefined_res = [];
   506         if (is_array($quest_vars) && count($quest_vars) > 0) {
   507             $result_has_undefined_vars = array_diff($defined_result_vars, $quest_vars);
   508             $question_has_unused_vars = array_diff($quest_vars, $defined_result_vars);
   511         if (is_array($result_vars) && count($result_vars) > 0) {
   512             $result_has_undefined_res = array_diff($defined_result_res, $result_vars);
   516         if (count($result_has_undefined_vars) > 0 || count($question_has_unused_vars) > 0) {
   517             if (count($result_has_undefined_vars) > 0) {
   518                 $error_message .= $this->
lng->txt(
"res_contains_undef_var") . 
'<br>';
   520             if (count($question_has_unused_vars) > 0) {
   521                 $error_message .= $this->
lng->txt(
"que_contains_unused_var") . 
'<br>';
   526                 $this->tpl->setOnScreenMessage(
'failure', $error_message);
   530         if (is_array($result_has_undefined_res) && count($result_has_undefined_res) > 0) {
   531             $error_message .= $this->
lng->txt(
"res_contains_undef_res") . 
'<br>';
   535         if ($save && !$checked) {
   536             $this->tpl->setOnScreenMessage(
'failure', $error_message);
   539         if ($this->
object->getId()) {
   541             $hidden->setValue($this->
object->getId());
   542             $form->addItem($hidden);
   547         $form->addCommandButton(
'parseQuestion', $this->
lng->txt(
"parseQuestion"));
   548         $form->addCommandButton(
'saveReturn', $this->
lng->txt(
"save_return"));
   549         $form->addCommandButton(
'save', $this->
lng->txt(
"save"));
   556             foreach ($this->request->getParsedBody() as 
$key => $value) {
   557                 if (preg_match(
"/^unit_(\\\$v\d+)$/", $key, $matches)) {
   558                     array_push($found_vars, $matches[1]);
   560                 if (preg_match(
"/^unit_(\\\$r\d+)$/", $key, $matches)) {
   561                     array_push($found_results, $matches[1]);
   566             foreach ($this->request->getParsedBody() as $key => $value) {
   567                 $item = $form->getItemByPostVar($key);
   568                 if ($item !== null) {
   569                     switch (get_class($item)) {
   570                         case 'ilDurationInputGUI':
   571                             $item->setHours($value[
'hh']);
   572                             $item->setMinutes($value[
'mm']);
   573                             $item->setSeconds($value[
'ss']);
   576                             $item->setValue($value);
   581             $check = array_merge($found_vars, $found_results);
   582             foreach ((array) $form->getItems() as $item) {
   583                 $postvar = $item->getPostVar();
   584                 if (preg_match(
"/_\\\$[r|v]\d+/", $postvar, $matches)) {
   585                     $k = substr(array_shift($matches), 1);
   586                     if (!in_array($k, 
$check)) {
   587                         $form->removeItemByPostVar($postvar);
   591             $variables = array_filter($variables, fn($k, $v) => in_array($v, 
$check), ARRAY_FILTER_USE_BOTH);
   594             $errors = !$form->checkInput();
   596             $custom_errors = 
false;
   597             if (count($variables)) {
   598                 foreach ($variables as $variable) {
   602                     $min_range = $form->getItemByPostVar(
'range_min_' . $variable->getVariable());
   603                     $max_range = $form->getItemByPostVar(
'range_max_' . $variable->getVariable());
   604                     if ($min_range->getValue() > $max_range->getValue()) {
   605                         $min_range->setAlert($this->
lng->txt(
'err_range'));
   606                         $max_range->setAlert($this->
lng->txt(
'err_range'));
   607                         $custom_errors = 
true;
   609                     $intPrecision = $form->getItemByPostVar(
'intprecision_' . $variable->getVariable());
   610                     $decimal_spots = $form->getItemByPostVar(
'precision_' . $variable->getVariable());
   611                     if ($decimal_spots->getValue() == 0
   612                         && $min_range->getValue() !== null
   613                         && $max_range->getValue() !== null
   614                         && !$variable->isIntPrecisionValid(
   615                             $intPrecision->getValue(),
   616                             $min_range->getValue(),
   617                             $max_range->getValue()
   620                         $intPrecision->setAlert($this->
lng->txt(
'err_division'));
   621                         $custom_errors = 
true;
   631                     $min_range = $form->getItemByPostVar(
'range_min_' . $result->getResult());
   632                     $max_range = $form->getItemByPostVar(
'range_max_' . $result->getResult());
   633                     if ($min_range->getValue() > $max_range->getValue()) {
   634                         $min_range->setAlert($this->
lng->txt(
'err_range'));
   635                         $max_range->setAlert($this->
lng->txt(
'err_range'));
   636                         $custom_errors = 
true;
   640                     $formula = $form->getItemByPostVar(
'formula_' . $result->getResult());
   641                     if (strpos($formula->getValue(), $result->getResult()) !== 
false) {
   642                         $formula->setAlert($this->
lng->txt(
'errRecursionInResult'));
   643                         $custom_errors = 
true;
   646                     $result_unit = $form->getItemByPostVar(
'unit_' . $result->getResult());
   647                     $rating_advanced = $form->getItemByPostVar(
'rating_advanced_' . $result->getResult());
   648                     if (((
int) $result_unit->getValue() <= 0) && $rating_advanced->getChecked()) {
   649                         unset($_POST[
'rating_advanced_' . $result->getResult()]);
   650                         $rating_advanced->setDisabled(
true);
   651                         $rating_advanced->setChecked(
false);
   652                         $rating_advanced->setAlert($this->
lng->txt(
'err_rating_advanced_not_allowed'));
   653                         $custom_errors = 
true;
   654                     } elseif ($rating_advanced->getChecked()) {
   655                         $rating_sign = $form->getItemByPostVar(
'rating_sign_' . $result->getResult());
   656                         $rating_value = $form->getItemByPostVar(
'rating_value_' . $result->getResult());
   657                         $rating_unit = $form->getItemByPostVar(
'rating_unit_' . $result->getResult());
   659                         $percentage = $rating_sign->getValue() + $rating_value->getValue() + $rating_unit->getValue();
   660                         if ($percentage != 100) {
   661                             $rating_advanced->setAlert($this->
lng->txt(
'err_wrong_rating_advanced'));
   662                             $custom_errors = 
true;
   666                     preg_match_all(
"/([$][v][0-9]*)/", $formula->getValue(), $form_vars);
   667                     $result_has_undefined_vars = array_diff($form_vars[0], $found_vars);
   668                     if (count($result_has_undefined_vars)) {
   670                         $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'res_contains_undef_var'));
   675             if ($custom_errors && !$errors) {
   677                 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'form_input_not_valid'));
   679             foreach ($this->request->getParsedBody() as $key => $value) {
   680                 $item = $form->getItemByPostVar($key);
   681                 if ($item !== null) {
   682                     switch (get_class($item)) {
   683                         case 'ilDurationInputGUI':
   684                             $item->setHours($value[
'hh']);
   685                             $item->setMinutes($value[
'mm']);
   686                             $item->setSeconds($value[
'ss']);
   689                             $item->setValue($value);
   699             $this->tpl->setVariable(
'QUESTION_DATA', $form->getHTML());
   706         if (array_key_exists($result->getResult(), $resultunits)) {
   707             if (array_key_exists($unit_id, $resultunits[$result->getResult()])) {
   723         $resultunit = $result->getUnit();
   731         if (is_object($resultunit)) {
   742         $this->editQuestion();
   750         if ((!$_POST[
"title"]) or (!$_POST[
"author"]) or (!$_POST[
"question"])) {
   774         $graphicalOutput = 
false,
   775         $result_output = 
false,
   776         $show_question_only = 
true,
   777         $show_feedback = 
false,
   778         $show_correct_solution = 
false,
   779         $show_manual_scoring = 
false,
   780         $show_question_text = 
true   784         if ($pass !== null) {
   785             $user_solution = $this->
object->getVariableSolutionValuesForPass($active_id, $pass);
   787             $user_solution = array_reduce(
   788                 $this->
object->fetchAllVariables($this->object->getQuestion()),
   797         if (($active_id > 0) && (!$show_correct_solution)) {
   798             $user_solution[
"active_id"] = $active_id;
   799             $user_solution[
"pass"] = $pass;
   800             $solutions = $this->
object->getSolutionValues($active_id, $pass);
   801             foreach ($solutions as $idx => $solution_value) {
   802                 if (preg_match(
"/^(\\\$v\\d+)$/", $solution_value[
"value1"], $matches)) {
   803                     $user_solution[$matches[1]] = $solution_value[
"value2"];
   804                 } elseif (preg_match(
"/^(\\\$r\\d+)$/", $solution_value[
"value1"], $matches)) {
   805                     if (!array_key_exists($matches[1], $user_solution)) {
   806                         $user_solution[$matches[1]] = array();
   808                     $user_solution[$matches[1]][
"value"] = $solution_value[
"value2"];
   809                 } elseif (preg_match(
"/^(\\\$r\\d+)_unit$/", $solution_value[
"value1"], $matches)) {
   810                     if (!array_key_exists($matches[1], $user_solution)) {
   811                         $user_solution[$matches[1]] = array();
   813                     $user_solution[$matches[1]][
"unit"] = $solution_value[
"value2"];
   816         } elseif ($active_id) {
   817             $user_solution = $this->
object->getBestSolution($this->
object->getSolutionValues($active_id, $pass));
   819             $solution_values = [];
   822             if (is_array($participantsSolution)) {
   823                 foreach ($participantsSolution as $val1 => $val2) {
   824                     $solution_values[] = array(
'value1' => $val1, 
'value2' => $val2);
   828             $user_solution = $this->
object->getBestSolution($solution_values);
   839             $show_correct_solution,
   840             $show_manual_scoring,
   848         mixed $user_solutions,
   851         bool $graphical_output = 
false,
   852         bool $result_output = 
false,
   853         bool $show_question_only = 
true,
   854         bool $show_feedback = 
false,
   855         bool $show_correct_solution = 
false,
   856         bool $show_manual_scoring = 
false,
   857         bool $show_question_text = 
true,
   858         bool $show_autosave_title = 
false,
   859         bool $show_inline_feedback = 
false,
   861         $template = 
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output_solution.html", 
true, 
true, 
'Modules/TestQuestionPool');
   862         $correctness_icons = [
   866         $questiontext = $this->
object->substituteVariables($user_solutions, $graphical_output, 
true, $result_output, $correctness_icons);
   868         $questionoutput = $template->get();
   869         $solutiontemplate = 
new ilTemplate(
"tpl.il_as_tst_solution_output.html", 
true, 
true, 
"Modules/TestQuestionPool");
   871         if (strlen($feedback)) {
   877             $solutiontemplate->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
   880         $solutiontemplate->setVariable(
"SOLUTION_OUTPUT", $questionoutput);
   882         $solutionoutput = $solutiontemplate->get();
   883         if (!$show_question_only) {
   887         return $solutionoutput;
   890     public function getPreview($show_question_only = 
false, $showInlineFeedback = 
false): string
   897             foreach ($solutions as $val1 => $val2) {
   898                 if (preg_match(
"/^(\\\$v\\d+)$/", $val1, $matches)) {
   899                     $user_solution[$matches[1]] = $val2;
   900                 } elseif (preg_match(
"/^(\\\$r\\d+)$/", $val1, $matches)) {
   901                     if (!array_key_exists($matches[1], $user_solution)) {
   902                         $user_solution[$matches[1]] = [];
   904                     $user_solution[$matches[1]][
"value"] = $val2;
   905                 } elseif (preg_match(
"/^(\\\$r\\d+)_unit$/", $val1, $matches)) {
   906                     if (!array_key_exists($matches[1], $user_solution)) {
   907                         $user_solution[$matches[1]] = [];
   909                     $user_solution[$matches[1]][
"unit"] = $val2;
   912                 if (preg_match(
"/^(\\\$r\\d+)/", $val1, $matches) && !isset($user_solution[$matches[1]][
"result_type"])) {
   918         if (!$this->
object->hasRequiredVariableSolutionValues($user_solution)) {
   919             $user_solution = $this->
object->getInitialVariableSolutionValues();
   926         $template = 
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output.html", 
true, 
true, 
'Modules/TestQuestionPool');
   928             $questiontext = $this->
object->substituteVariables($user_solution);
   930             $questiontext = $this->
object->substituteVariables([]);
   933         $questionoutput = $template->get();
   934         if (!$show_question_only) {
   938         return $questionoutput;
   942     public function getTestOutput($active_id, $pass, $is_postponed = 
false, $use_post_solutions = 
false, $show_feedback = 
false): string
   945         $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'enter_valid_values'));
   949             $solutions = $this->
object->getTestOutputSolutions($active_id, $pass);
   950             $actualPassIndex = null;
   951             if ($this->
object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
   955             foreach ($solutions as $idx => $solution_value) {
   956                 if (preg_match(
"/^(\\\$v\\d+)$/", $solution_value[
'value1'], $matches)) {
   957                     if ($this->
object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
   958                         $this->
object->saveCurrentSolution($active_id, $actualPassIndex, $matches[1], $solution_value[
'value2'], 
true);
   961                     $user_solution[$matches[1]] = $solution_value[
'value2'];
   962                 } elseif (preg_match(
"/^(\\\$r\\d+)$/", $solution_value[
'value1'], $matches)) {
   963                     if (!array_key_exists($matches[1], $user_solution)) {
   964                         $user_solution[$matches[1]] = [];
   966                     $user_solution[$matches[1]][
"value"] = $solution_value[
'value2'];
   967                 } elseif (preg_match(
"/^(\\\$r\\d+)_unit$/", $solution_value[
'value1'], $matches)) {
   968                     if (!array_key_exists($matches[1], $user_solution)) {
   969                         $user_solution[$matches[1]] = [];
   971                     $user_solution[$matches[1]][
"unit"] = $solution_value[
'value2'];
   973                 if (preg_match(
"/^(\\\$r\\d+)/", $solution_value[
'value1'], $matches) && !isset($user_solution[$matches[1]][
"result_type"])) {
   979         $solutions = $this->
object->getSolutionValues($active_id, $pass, 
true);
   980         foreach ($solutions as $idx => $solution_value) {
   981             if (preg_match(
"/^(\\\$v\\d+)$/", $solution_value[
'value1'], $matches)) {
   982                 $user_solution[$matches[1]] = $solution_value[
'value2'];
   986         if ($user_solution === []) {
   987             $user_solution = $this->
object->getVariableSolutionValuesForPass($active_id, $pass);
   991         $template = 
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output.html", 
true, 
true, 
'Modules/TestQuestionPool');
   993         $questiontext = $this->
object->substituteVariables($user_solution);
   997         $questionoutput = $template->get();
   998         $pageoutput = $this->
outQuestionPage(
"", $is_postponed, $active_id, $questionoutput);
 
hasCorrectSolution($activeId, $passIndex)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
static getInstance($identifier)
 
generateCorrectnessIconsForCorrectness(int $correctness)
 
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...
 
addTarget(string $a_text, string $a_link, $a_cmd="", $a_cmdClass="", string $a_frame="", bool $a_activate=false, bool $a_dir_text=false)
 
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
 
const CSS_CLASS_FEEDBACK_CORRECT
 
populateTaxonomyFormSection(ilPropertyFormGUI $form)
 
const CSS_CLASS_FEEDBACK_WRONG
 
Basic GUI class for assessment questions. 
 
saveTaxonomyAssignments()
 
getILIASPage(string $html="")
Returns the ILIAS Page around a question. 
 
addSaveOnEnterOnLoadCode()
 
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
 
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins 
 
addErrorMessage(string $errormessage)
 
getGenericFeedbackOutput(int $active_id, ?int $pass)