19 declare(strict_types=1);
    67         for ($i = count($this->answers); $i < self::NUM_REQUIRED_ANSWERS; $i++) {
    69             $answer->setPosition($i);
    70             $this->answers[$answer->getPosition()] = $answer;
    76         return 'assKprimChoice';
    81         return "qpl_qst_kprim";
   175             $answer->setAnswertext(
   194             if ($answer->getPosition() == $position) {
   207         $this->answers[] = $answer;
   214         while (
$data = $this->db->fetchAssoc(
$res)) {
   215             $this->
setId($questionId);
   236             if (is_numeric($data[
'thumb_size'])) {
   244             if ($data[
'custom_true'] !== null) {
   248             if ($data[
'custom_false'] !== null) {
   252             if ($data[
'score_partsol'] !== null) {
   256             if (isset($data[
'feedback_setting'])) {
   274         parent::loadFromDb($questionId);
   279         $res = $this->db->queryF(
   280             "SELECT * FROM {$this->getAnswerTableName()} WHERE question_fi = %s ORDER BY position ASC",
   285         while (
$data = $this->db->fetchAssoc(
$res)) {
   288             $answer->setPosition(
$data[
'position']);
   292             $answer->setImageFile(
$data[
'imagefile']);
   293             $answer->setThumbPrefix($this->getThumbPrefix());
   297             $answer->setCorrectness(
$data[
'correctness']);
   299             $this->answers[$answer->getPosition()] = $answer;
   317                 'question_fi' => [
'integer', $this->
getId()]
   338                     'question_fi' => [
'integer', $this->
getId()],
   339                     'position' => [
'integer', (
int) $answer->getPosition()]
   342                     'answertext' => [
'text', $answer->getAnswertext()],
   343                     'imagefile' => [
'text', $answer->getImageFile()],
   344                     'correctness' => [
'integer', (
int) $answer->getCorrectness()]
   352         foreach ([$this->title, $this->author, $this->question] as 
$text) {
   353             if (!strlen($text)) {
   358         if (!isset($this->points)) {
   365             if (is_null($answer->getCorrectness())) {
   370                 (!is_string($answer->getAnswertext()) || $answer->getAnswertext() === 
'') &&
   371                 (!is_string($answer->getImageFile()) || $answer->getImageFile() === 
'')
   383         bool $authorized = 
true   385         if ($pass === null) {
   391             function () use ($answer, $active_id, $pass, $authorized) {
   393                 foreach ($answer as $index => $value) {
   394                     if ($value !== null) {
   407         bool $authorized_solution = 
true   410         if (is_null($pass)) {
   416         while (
$data = $this->db->fetchAssoc($result)) {
   417             $found_values[(
int) 
$data[
'value1']] = (
int) 
$data[
'value2'];
   427         return [self::ANSWER_TYPE_SINGLE_LINE, self::ANSWER_TYPE_MULTI_LINE];
   433         return in_array($answerType, $validTypes);
   448             self::ANSWER_TYPE_SINGLE_LINE => $lng->
txt(
'answers_singleline'),
   449             self::ANSWER_TYPE_MULTI_LINE => $lng->
txt(
'answers_multiline')
   456             self::OPTION_LABEL_RIGHT_WRONG,
   457             self::OPTION_LABEL_PLUS_MINUS,
   458             self::OPTION_LABEL_APPLICABLE_OR_NOT,
   459             self::OPTION_LABEL_ADEQUATE_OR_NOT,
   460             self::OPTION_LABEL_CUSTOM
   468             function (array 
$c, 
string $option_label) use ($lng): array {
   478         return match ($option_label) {
   479             self::OPTION_LABEL_RIGHT_WRONG => 
'option_label_right_wrong',
   480             self::OPTION_LABEL_PLUS_MINUS => 
'option_label_plus_minus',
   481             self::OPTION_LABEL_APPLICABLE_OR_NOT => 
'option_label_applicable_or_not',
   482             self::OPTION_LABEL_ADEQUATE_OR_NOT => 
'option_label_adequate_or_not',
   483             self::OPTION_LABEL_CUSTOM => 
'option_label_custom'   490         return in_array($option_label, $valid_labels);
   495         if ($option_label === self::OPTION_LABEL_CUSTOM) {
   506         switch ($option_label) {
   507             case self::OPTION_LABEL_RIGHT_WRONG:
   508                 return 'option_label_right';
   510             case self::OPTION_LABEL_PLUS_MINUS:
   511                 return 'option_label_plus';
   513             case self::OPTION_LABEL_APPLICABLE_OR_NOT:
   514                 return 'option_label_applicable';
   516             case self::OPTION_LABEL_ADEQUATE_OR_NOT:
   517                 return 'option_label_adequate';
   520                 throw new \ErrorException(
'Invalide  Option Label');
   526         if ($option_label === self::OPTION_LABEL_CUSTOM) {
   537         switch ($option_label) {
   538             case self::OPTION_LABEL_RIGHT_WRONG:
   539                 return 'option_label_wrong';
   541             case self::OPTION_LABEL_PLUS_MINUS:
   542                 return 'option_label_minus';
   544             case self::OPTION_LABEL_APPLICABLE_OR_NOT:
   545                 return 'option_label_not_applicable';
   547             case self::OPTION_LABEL_ADEQUATE_OR_NOT:
   548                 return 'option_label_not_adequate';
   551                 throw new \ErrorException(
'Invalide  Option Label');
   558             $lng->
txt(
'kprim_instruction_text'),
   566         return $labelValue == self::OPTION_LABEL_CUSTOM;
   574             if (!isset($files[$answer->getPosition()])) {
   586         if (!file_exists($imagePath)) {
   608         if (file_exists($answer->getImageFsPath())) {
   612         if (file_exists($answer->getThumbFsPath())) {
   616         $answer->setImageFile(null);
   621         $solutionSubmit = [];
   622         $post = $this->dic->http()->wrapper()->post();
   625             if (
$post->has(
"kprim_choice_result_$index")) {
   626                 $value = 
$post->retrieve(
   627                     "kprim_choice_result_$index",
   628                     $this->dic->refinery()->kindlyTo()->string()
   630                 if (is_numeric($value)) {
   631                     $solutionSubmit[] = $value;
   634                 $solutionSubmit[] = null;
   637         return $solutionSubmit;
   643         if ($found_values === null) {
   647             if (!isset($found_values[$answer->getPosition()])) {
   651             if ($found_values[$answer->getPosition()] == $answer->getCorrectness()) {
   656         if ($numCorrect >= self::NUM_REQUIRED_ANSWERS) {
   665             if (count($found_values) == 0) {
   687         $combinedText = parent::getRTETextWithMediaObjects();
   690             $combinedText .= $answer->getAnswertext();
   693         return $combinedText;
   712         $this->
lng->loadLanguageModule(
'assessment');
   715         $result[
'id'] = $this->
getId();
   725         $result[
'feedback'] = [
   726             'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
false)),
   727             'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
true))
   738         foreach ($this->
getAnswers() as $key => $answer) {
   739             if (strlen((
string) $answer->getImageFile())) {
   745                 'correctness' => (
bool) $answer->getCorrectness(),
   746                 'order' => (
int) $answer->getPosition(),
   747                 'image' => (string) $answer->getImageFile(),
   749                     $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), 0, $key)
   762         $result[
'mobs'] = $mobs;
   764         return json_encode($result);
   770             return self::NUM_REQUIRED_ANSWERS - self::PARTIAL_SCORING_NUM_CORRECT_ANSWERS;
   778         return 'feedback_correct_kprim';
   783         if ($position < 0 || $position >= (self::NUM_REQUIRED_ANSWERS - 1)) {
   787         for ($i = 0, $max = count($this->answers); $i < $max; $i++) {
   788             if ($i == $position) {
   789                 $movingAnswer = $this->answers[$i];
   790                 $targetAnswer = $this->answers[ $i + 1 ];
   792                 $movingAnswer->setPosition($position + 1);
   793                 $targetAnswer->setPosition($position);
   795                 $this->answers[ $i + 1 ] = $movingAnswer;
   796                 $this->answers[$i] = $targetAnswer;
   804         if ($position <= 0 || $position > (self::NUM_REQUIRED_ANSWERS - 1)) {
   808         for ($i = 0, $max = count($this->answers); $i < $max; $i++) {
   809             if ($i == $position) {
   810                 $movingAnswer = $this->answers[$i];
   811                 $targetAnswer = $this->answers[ $i - 1 ];
   813                 $movingAnswer->setPosition($position - 1);
   814                 $targetAnswer->setPosition($position);
   816                 $this->answers[ $i - 1 ] = $movingAnswer;
   817                 $this->answers[$i] = $targetAnswer;
   827             AdditionalInformationGenerator::KEY_QUESTION_TYPE => (string) $this->
getQuestionType(),
   830             AdditionalInformationGenerator::KEY_QUESTION_KPRIM_OPTION_LABEL => $additional_info
   832             AdditionalInformationGenerator::KEY_QUESTION_SHUFFLE_ANSWER_OPTIONS => $additional_info
   834             AdditionalInformationGenerator::KEY_FEEDBACK => [
   835                 AdditionalInformationGenerator::KEY_QUESTION_FEEDBACK_ON_INCOMPLETE => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
false)),
   836                 AdditionalInformationGenerator::KEY_QUESTION_FEEDBACK_ON_COMPLETE => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(), 
true))
   840         $result[AdditionalInformationGenerator::KEY_QUESTION_KPRIM_SCORE_PARTIAL_SOLUTION_ENABLED] = $additional_info
   844         foreach ($this->
getAnswers() as $key => $answer) {
   846                 AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTION => $this->
formatSAQuestion($answer->getAnswertext() ?? 
''),
   847                 AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTION_CORRECTNESS => $additional_info->
getTrueFalseTagForBool((
bool) $answer->getCorrectness()),
   848                 AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTION_ORDER => (
int) $answer->getPosition(),
   849                 AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTION_IMAGE => (string) $answer->getImageFile(),
   851                     $this->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation($this->getId(), 0, $key)
   856         $result[AdditionalInformationGenerator::KEY_QUESTION_ANSWER_OPTIONS] = 
$answers;
   863         array $solution_values
   865         $parsed_solution = [];
   866         $true_option_label = $this->
getOptionLabel() === self::OPTION_LABEL_CUSTOM
   869         $false_option_label = $this->
getOptionLabel() === self::OPTION_LABEL_CUSTOM
   874             foreach ($solution_values as $solution) {
   875                 if ($solution[
'value1'] !== (
string) 
$id) {
   879                 $value = $false_option_label;
   880                 if ($solution[
'value2'] === 
'1') {
   881                     $value = $true_option_label;
   885             $parsed_solution[$answer->getAnswertext()] = $value;
   887         return $parsed_solution;
   892         $parsed_solution = [];
   896             $value = $this->
lng->txt(
'none');
   897             foreach ($solution_values as $solution) {
   898                 if ($solution[
'value1'] !== (
string) 
$id) {
   902                 $value = $false_option_label;
   903                 if ($solution[
'value2'] === 
'1') {
   904                     $value = $true_option_label;
   908             $parsed_solution[] = 
"{$answer->getAnswertext()} ({$value})";
   910         return $parsed_solution;
   919                 . 
' (' . $v->
getCorrectness() ? $true_option_label : $false_option_label . 
')',
 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...
 
getValidOptionLabelsTranslated(ilLanguage $lng)
 
setNrOfTries(int $a_nr_of_tries)
 
static getInstance($identifier)
 
setImageFsDir($imageFsDir)
 
isValidAnswerType($answerType)
 
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test. 
 
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table. 
 
getRTETextWithMediaObjects()
 
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
 
setImageFile(?string $imageFile)
 
setScorePartialSolutionEnabled($scorePartialSolutionEnabled)
 
const OPTION_LABEL_RIGHT_WRONG
 
isCustomOptionLabel($labelValue)
 
loadAnswerData(int $question_id)
 
__construct($title='', $comment='', $author='', $owner=-1, $question='')
 
isValidOptionLabel(?string $option_label)
 
const OPTION_LABEL_ADEQUATE_OR_NOT
 
const NUM_REQUIRED_ANSWERS
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
getImagePathWeb()
Returns the web image path for web accessable images of a question. 
 
const PARTIAL_SCORING_NUM_CORRECT_ANSWERS
 
removeAnswerImage($position)
 
lmMigrateQuestionTypeSpecificContent(ilAssSelfAssessmentMigrator $migrator)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
getSpecificFeedbackSetting()
 
migrateToLmContent($content)
 
moveAnswerDown($position)
 
setOptionLabel(string $option_label)
 
getSpecificFeedbackAllCorrectOptionLabel()
 
setCustomTrueOptionLabel($customTrueOptionLabel)
 
static makeDirParents(string $a_dir)
Create a new directory and all parent directories. 
 
setComment(string $comment="")
 
addAnswer(ilAssKprimChoiceAnswer $answer)
 
toLog(AdditionalInformationGenerator $additional_info)
 
const ANSWER_TYPE_MULTI_LINE
 
isScorePartialSolutionEnabled()
 
saveCurrentSolution(int $active_id, int $pass, $value1, $value2, bool $authorized=true, $tstamp=0)
 
getImagePath($question_id=null, $object_id=null)
Returns the image path for web accessable images of a question. 
 
buildHashedImageFilename(string $plain_image_filename, bool $unique=false)
 
isSingleLineAnswerType($answerType)
 
getAnswerTypeSelectOptions(ilLanguage $lng)
 
saveWorkingData(int $active_id, ?int $pass=null, bool $authorized=true)
 
calculateReachedPoints(int $active_id, ?int $pass=null, bool $authorized_solution=true)
 
getTrueOptionLabel(string $option_label)
 
bool $shuffle_answers_enabled
 
cloneQuestionTypeSpecificProperties(\assQuestion $target)
 
isShuffleAnswersEnabled()
 
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively 
 
setLastChange(int $lastChange)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
const OPTION_LABEL_APPLICABLE_OR_NOT
 
solutionValuesToLog(AdditionalInformationGenerator $additional_info, array $solution_values)
 
getTrueOptionLabelTranslation(ilLanguage $lng, string $option_label)
 
getCustomFalseOptionLabel()
 
handleFileUploads($answers, $files)
 
getFalseOptionLabel(string $option_label)
 
setSpecificFeedbackSetting(int $specific_feedback_setting)
 
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file 
 
saveQuestionDataToDb(?int $original_id=null)
 
string $customFalseOptionLabel
 
getInstructionTextTranslation(ilLanguage $lng, $option_label)
 
calculateReachedPointsForSolution(?array $found_values, int $active_id=0)
 
setShuffleAnswersEnabled(bool $shuffle_answers_enabled)
 
setCustomFalseOptionLabel($customFalseOptionLabel)
 
const OPTION_LABEL_CUSTOM
 
getSolutionMaxPass(int $active_id)
 
removeCurrentSolution(int $active_id, int $pass, bool $authorized=true)
 
saveToDb(?int $original_id=null)
 
const FEEDBACK_SETTING_ALL
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
__construct(Container $dic, ilPlugin $plugin)
 
setOriginalId(?int $original_id)
 
setTitle(string $title="")
 
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples 
 
setThumbSize(int $thumbSize)
 
setLifecycle(ilAssQuestionLifecycle $lifecycle)
 
bool $scorePartialSolutionEnabled
 
getCustomTrueOptionLabel()
 
getCurrentSolutionResultSet(int $active_id, int $pass, bool $authorized=true)
 
handleFileUpload(ilAssKprimChoiceAnswer $answer, $fileData)
 
saveAdditionalQuestionDataToDb()
Saves a record to the question types additional data table. 
 
solutionValuesToText(array $solution_values)
 
string $customTrueOptionLabel
 
getFalseOptionLabelTranslation(ilLanguage $lng, string $option_label)
 
int $specific_feedback_setting
 
getHtmlQuestionContentPurifier()
 
setAuthor(string $author="")
 
getCorrectSolutionForTextOutput(int $active_id, int $pass)
 
const OPTION_LABEL_PLUS_MINUS
 
getLangVarForOptionLabel(string $option_label)
 
setAdditionalContentEditingMode(?string $additionalContentEditingMode)
 
setAnswerType($answerType)
 
static getDraftInstance()
 
const ANSWER_TYPE_SINGLE_LINE
 
toJSON()
Returns a JSON representation of the question. 
 
setAnswertext($answertext)
 
setQuestion(string $question="")