19 declare(strict_types=1);
    52             count($this->answers) >= $this->correctanswers
    71         $result = $this->db->queryF(
    76         if ($result->numRows() == 1) {
    77             $data = $this->db->fetchAssoc($result);
    78             $this->
setId($question_id);
    82             $this->
setComment((
string) $data[
'description']);
   104         $result = $this->db->queryF(
   105             "SELECT * FROM qpl_a_textsubset WHERE question_fi = %s ORDER BY aorder ASC",
   109         if ($result->numRows() > 0) {
   110             while (
$data = $this->db->fetchAssoc($result)) {
   115         parent::loadFromDb($question_id);
   125         if (array_key_exists($order, $this->answers)) {
   129             for ($i = 0; $i < $order; $i++) {
   130                 $newchoices[] = $this->answers[$i];
   132             $newchoices[] = $answer;
   133             for ($i = $order, $iMax = count($this->answers); $i < $iMax; $i++) {
   134                 $changed = $this->answers[$i];
   135                 $changed->setOrder($i + 1);
   136                 $newchoices[] = $changed;
   138             $this->answers = $newchoices;
   154         return count($this->answers);
   171         if (count($this->answers) < 1) {
   174         if ($index >= count($this->answers)) {
   178         return $this->answers[$index];
   194         if (count($this->answers) < 1) {
   197         if ($index >= count($this->answers)) {
   200         unset($this->answers[$index]);
   201         $this->answers = array_values($this->answers);
   202         for ($i = 0, $iMax = count($this->answers); $i < $iMax; $i++) {
   203             if ($this->answers[$i]->
getOrder() > $index) {
   204                 $this->answers[$i]->setOrder($i);
   229         foreach ($this->answers as $answer) {
   230             if ($answer->getPoints() > 0) {
   231                 $points[] = $answer->getPoints();
   237             if (isset(
$points[$counter])) {
   238                 $maxpoints += 
$points[$counter];
   252         $available_answers = [];
   253         foreach ($this->answers as $answer) {
   254             $available_answers[] = $answer->getAnswertext();
   256         return $available_answers;
   275         foreach ($answers as $key => $value) {
   276             if ($this->answers[$key]->
getPoints() <= 0) {
   279             $value = html_entity_decode($value); #SB
   280             switch ($textrating) {
   287                     if (strcmp($value, $answer) == 0) {
   292                     $transformation = 
$refinery->string()->levenshtein()->standard($answer, 1);
   295                     $transformation = 
$refinery->string()->levenshtein()->standard($answer, 2);
   298                     $transformation = 
$refinery->string()->levenshtein()->standard($answer, 3);
   301                     $transformation = 
$refinery->string()->levenshtein()->standard($answer, 4);
   304                     $transformation = 
$refinery->string()->levenshtein()->standard($answer, 5);
   309             if (isset($transformation) && $transformation->transform($value) >= 0) {
   323         switch ($text_rating) {
   342         bool $authorized_solution = 
true   344         if ($pass === null) {
   350         while (
$data = $this->db->fetchAssoc($result)) {
   351             $enteredTexts[] = 
$data[
'value1'];
   359         $this->correctanswers = $a_correct_answers;
   370         bool $authorized = 
true   372         if ($pass === null) {
   378             function () use ($active_id, $pass, $authorized, $solution_submit) {
   381                 foreach ($solution_submit as $value) {
   395         $this->db->manipulateF(
   401         $this->db->manipulateF(
   403             ) . 
" (question_fi, textgap_rating, correctanswers) VALUES (%s, %s, %s)",
   404             [ 
"integer", 
"text", 
"integer" ],
   415         $this->db->manipulateF(
   416             "DELETE FROM qpl_a_textsubset WHERE question_fi = %s",
   421         foreach ($this->answers as $key => $value) {
   422             $answer_obj = $this->answers[$key];
   423             $next_id = $this->db->nextId(
'qpl_a_textsubset');
   424             $this->db->manipulateF(
   425                 "INSERT INTO qpl_a_textsubset (answer_id, question_fi, answertext, points, aorder, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
   426                 [ 
'integer', 
'integer', 
'text', 
'float', 
'integer', 
'integer' ],
   430                                         $answer_obj->getAnswertext(),
   431                                         $answer_obj->getPoints(),
   432                                         $answer_obj->getOrder(),
   447         return "assTextSubset";
   457         foreach ($this->answers as $answer) {
   458             $key = $answer->getPoints() . 
'';
   460             if (!isset($join[$key]) || !is_array($join[$key])) {
   464             $join[$key][] = $answer->getAnswertext();
   479         foreach ($this->answers as $answer) {
   480             $len = strlen($answer->getAnswertext());
   481             if ($len > $maxwidth) {
   485         return $maxwidth + 3;
   496         return "qpl_qst_textsubset";
   507         return "qpl_a_textsubset";
   516         return parent::getRTETextWithMediaObjects();
   530         $result[
'id'] = $this->
getId();
   536         $result[
'feedback'] = [
   537             'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
false)),
   538             'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
true))
   542         foreach ($this->
getAnswers() as $key => $answer_obj) {
   544                 "answertext" => (string) $answer_obj->getAnswertext(),
   545                 "points" => (float) $answer_obj->getPoints(),
   546                 "order" => (
int) $answer_obj->getOrder()
   549         $result[
'correct_answers'] = 
$answers;
   560         $result[
'mobs'] = $mobs;
   562         return json_encode($result);
   571         $post = $this->dic->http()->wrapper()->post();
   573         $solutionSubmit = [];
   575             if (
$post->has(
"TEXTSUBSET_$index")) {
   576                 $value = 
$post->retrieve(
   578                     $this->dic->refinery()->kindlyTo()->string()
   582                     $value = $purifier->purify($value);
   583                     $solutionSubmit[] = $value;
   588         return $solutionSubmit;
   593         $enteredTexts ??= [];
   596         foreach ($enteredTexts as $enteredtext) {
   597             $index = $this->
isAnswerCorrect($available_answers, html_entity_decode($enteredtext));
   598             if ($index !== 
false) {
   599                 unset($available_answers[$index]);
   600                 $points += $this->answers[$index]->getPoints();
   608         return ilOperatorsExpressionMapping::getOperatorsByExpression($expression);
   629             $data = $this->db->queryF(
   630                 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s ORDER BY solution_id",
   631                 [
"integer", 
"integer", 
"integer",
"integer"],
   632                 [$active_id, $pass, $this->
getId(), $maxStep]
   635             $data = $this->db->queryF(
   636                 "SELECT value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s ORDER BY solution_id",
   637                 [
"integer", 
"integer", 
"integer"],
   638                 [$active_id, $pass, $this->
getId()]
   642         for ($index = 1; $index <= $this->db->numRows(
$data); ++$index) {
   643             $row = $this->db->fetchAssoc(
$data);
   644             $result->addKeyValue($index, $row[
"value1"]);
   650         $result->setReachedPercentage((
$points / $max_points) * 100);
   663         if ($index !== null) {
   675             if ($answerOptionValue !== $item->getAnswerText()) {
   688         $this->
addAnswer($answerOptionValue, $points, $qIndex);
   694             AdditionalInformationGenerator::KEY_QUESTION_TYPE => (string) $this->
getQuestionType(),
   697             AdditionalInformationGenerator::KEY_QUESTION_TEXT_MATCHING_METHOD => $additional_info->
getTagForLangVar(
   700             AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTIONS => 
array_map(
   702                     AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTION => $answer->
getAnswertext(),
   703                     AdditionalInformationGenerator::KEY_QUESTION_REACHABLE_POINTS => $answer->
getPoints()
   707             AdditionalInformationGenerator::KEY_FEEDBACK => [
   708                 AdditionalInformationGenerator::KEY_QUESTION_FEEDBACK_ON_INCOMPLETE => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
false)),
   709                 AdditionalInformationGenerator::KEY_QUESTION_FEEDBACK_ON_COMPLETE => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
true))
   716         switch ($matching_method) {
   718                 return 'cloze_textgap_case_insensitive';
   720                 return 'cloze_textgap_case_sensitive';
   722                 return 'cloze_textgap_levenshtein_of:1';
   724                 return 'cloze_textgap_levenshtein_of:2';
   726                 return 'cloze_textgap_levenshtein_of:3';
   728                 return 'cloze_textgap_levenshtein_of:4';
   730                 return 'cloze_textgap_levenshtein_of:5';
   738         array $solution_values
   741             static fn(array $v): 
string => $v[
'value1'],
   749             static fn(array $v): 
string => $v[
'value1'],
 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...
 
setNrOfTries(int $a_nr_of_tries)
 
calculateReachedPoints(int $active_id, ?int $pass=null, bool $authorized_solution=true)
 
addAnswer($answertext, $points, $order)
Adds an answer to the question. 
 
static getInstance($identifier)
 
calculateReachedPointsForSolution(?array $enteredTexts)
 
const PercentageResultExpression
 
getOperators(string $expression)
Get all available operations for a specific question. 
 
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. 
 
flushAnswers()
Deletes all answers. 
 
setCorrectAnswers(int $a_correct_answers)
 
toLog(AdditionalInformationGenerator $additional_info)
 
Class for answers with a binary state indicator. 
 
const TEXTGAP_RATING_LEVENSHTEIN3
 
& joinAnswers()
Returns the answers of the question as a comma separated string. 
 
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question. 
 
saveToDb(?int $original_id=null)
 
toJSON()
Returns a JSON representation of the question. 
 
loadFromDb(int $question_id)
 
getAnswerTableName()
Returns the name of the answer table in the database. 
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
Class for TextSubset questions. 
 
const TEXTGAP_RATING_CASEINSENSITIVE
 
const TEXTGAP_RATING_LEVENSHTEIN5
 
const StringResultExpression
 
const TEXTGAP_RATING_LEVENSHTEIN2
 
setComment(string $comment="")
 
const TEXTGAP_RATING_CASESENSITIVE
 
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
 
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
 
getQuestionType()
Returns the question type of the question. 
 
getAvailableAnswers()
Returns the available answers for the question. 
 
getUserQuestionResult(int $active_id, int $pass)
Get the user solution for a question by active_id and the test pass. 
 
const TEXTGAP_RATING_LEVENSHTEIN1
 
getPoints()
Gets the points. 
 
saveCurrentSolution(int $active_id, int $pass, $value1, $value2, bool $authorized=true, $tstamp=0)
 
addAnswerOptionValue(int $qIndex, string $answerOptionValue, float $points)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
setTextRating(string $text_rating)
 
const NumericResultExpression
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
getAnswerCount()
Returns the number of answers. 
 
getHtmlUserSolutionPurifier()
 
getAdditionalTableName()
Returns the name of the additional question data table in the database. 
 
saveQuestionDataToDb(?int $original_id=null)
 
getMatchingMethodLangVar(string $matching_method)
 
saveWorkingData(int $active_id, ?int $pass=null, bool $authorized=true)
 
getExpressionTypes()
Get all available expression types for a specific question. 
 
isAddableAnswerOptionValue(int $qIndex, string $answerOptionValue)
 
solutionValuesToText(array $solution_values)
 
getCorrectSolutionForTextOutput(int $active_id, int $pass)
 
getAnswertext()
Gets the answer text. 
 
getAnswer($index=0)
Returns an answer with a given index. 
 
getSolutionMaxPass(int $active_id)
 
static extendedTrim(string $value)
Trim non-printable characters from the beginning and end of a string. 
 
removeCurrentSolution(int $active_id, int $pass, bool $authorized=true)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
setOriginalId(?int $original_id)
 
solutionValuesToLog(AdditionalInformationGenerator $additional_info, array $solution_values)
 
setTitle(string $title="")
 
static strToLower(string $a_string)
 
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table. 
 
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples 
 
setLifecycle(ilAssQuestionLifecycle $lifecycle)
 
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table. 
 
getCurrentSolutionResultSet(int $active_id, int $pass, bool $authorized=true)
 
deleteAnswer($index=0)
Deletes an answer with a given index. 
 
getMaxTextboxWidth()
Returns the maximum width needed for the answer textboxes. 
 
lookupMaxStep(int $active_id, int $pass)
 
setAuthor(string $author="")
 
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
 
isAnswerCorrect($answers, $answer)
Returns the index of the found answer, if the given answer is in the set of correct answers and match...
 
static getDraftInstance()
 
const TEXTGAP_RATING_LEVENSHTEIN4
 
setQuestion(string $question="")
 
const EmptyAnswerExpression