64 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $item) {
68 $answers = implode(
' / ', $answers);
71 $this->
lng->txt(
'ass_cloze_gap_fb_gap_label'),
80 $this->
lng->txt(
'ass_cloze_gap_fb_txt_match_label'),
88 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_txt_nomatch_label'), $gapIndex + 1);
93 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_txt_empty_label'), $gapIndex + 1);
99 $this->
lng->txt(
'ass_cloze_gap_fb_sel_opt_label'),
107 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_sel_empty_label'), $gapIndex + 1);
112 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_num_valuehit_label'), $gapIndex + 1);
117 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_num_rangehit_label'), $gapIndex + 1);
122 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_num_toolow_label'), $gapIndex + 1);
127 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_num_toohigh_label'), $gapIndex + 1);
132 return sprintf($this->
lng->txt(
'ass_cloze_gap_fb_num_empty_label'), $gapIndex + 1);
137 if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
139 $header->setTitle($this->
lng->txt(
'feedback_answers'));
143 $this->
lng->txt(
'ass_cloze_fb_mode'),
150 $this->
lng->txt(
'ass_cloze_fb_mode_gap_qst'),
151 self::FB_MODE_GAP_QUESTION,
152 $this->
lng->txt(
'ass_cloze_fb_mode_gap_qst_info')
155 $feedbackMode->addOption($fbModeGapQuestion);
158 $this->
lng->txt(
'ass_cloze_fb_mode_gap_answ'),
159 self::FB_MODE_GAP_ANSWERS,
160 $this->
lng->txt(
'ass_cloze_fb_mode_gap_answ_info')
163 $feedbackMode->addOption($fbModeGapAnswers);
169 foreach ($this->questionOBJ->getGaps() as $gapIndex => $gap) {
179 $this->questionOBJ->isAdditionalContentEditingModePageObject()
187 foreach ($this->questionOBJ->getGaps() as $gapIndex => $gap) {
188 switch ($gap->getType()) {
209 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $answerIndex => $item) {
215 $propertyPostVar =
"feedback_answer_{$gapIndex}_{$answerIndex}";
220 $this->questionOBJ->isAdditionalContentEditingModePageObject()
229 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_TEXT_GAP_NOMATCH_INDEX;
234 $this->questionOBJ->isAdditionalContentEditingModePageObject()
242 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_TEXT_GAP_EMPTY_INDEX;
247 $this->questionOBJ->isAdditionalContentEditingModePageObject()
253 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $optIndex => $item) {
259 $propertyPostVar =
"feedback_answer_{$gapIndex}_{$optIndex}";
264 $this->questionOBJ->isAdditionalContentEditingModePageObject()
273 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_SELECT_GAP_EMPTY_INDEX;
278 $this->questionOBJ->isAdditionalContentEditingModePageObject()
294 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_NUMERIC_GAP_VALUE_HIT_INDEX;
299 $this->questionOBJ->isAdditionalContentEditingModePageObject()
308 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_NUMERIC_GAP_RANGE_HIT_INDEX;
313 $this->questionOBJ->isAdditionalContentEditingModePageObject()
322 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_NUMERIC_GAP_TOO_LOW_INDEX;
327 $this->questionOBJ->isAdditionalContentEditingModePageObject()
335 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_NUMERIC_GAP_TOO_HIGH_INDEX;
340 $this->questionOBJ->isAdditionalContentEditingModePageObject()
348 $propertyPostVar =
"feedback_answer_{$gapIndex}_" . self::FB_NUMERIC_GAP_EMPTY_INDEX;
353 $this->questionOBJ->isAdditionalContentEditingModePageObject()
359 if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
362 $fbMode->setValue($this->questionOBJ->getFeedbackMode());
364 if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
368 switch ($this->questionOBJ->getFeedbackMode()) {
369 case self::FB_MODE_GAP_QUESTION:
374 case self::FB_MODE_GAP_ANSWERS:
385 foreach ($this->questionOBJ->getGaps() as $gapIndex => $gap) {
393 foreach ($this->questionOBJ->getGaps() as $gapIndex => $gap) {
394 switch ($gap->getType()) {
415 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $answerIndex => $item) {
432 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $optIndex => $item) {
470 if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
473 if ($fbMode != $this->questionOBJ->getFeedbackMode()) {
479 switch ($this->questionOBJ->getFeedbackMode()) {
480 case self::FB_MODE_GAP_QUESTION:
485 case self::FB_MODE_GAP_ANSWERS:
495 foreach ($this->questionOBJ->getGaps() as $gapIndex => $gap) {
500 $this->questionOBJ->getId(),
502 self::SINGLE_GAP_FB_ANSWER_INDEX,
510 foreach ($this->questionOBJ->getGaps() as $gapIndex => $gap) {
511 switch ($gap->getType()) {
532 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $answerIndex => $item) {
536 $this->questionOBJ->getId(),
546 $this->questionOBJ->getId(),
548 self::FB_TEXT_GAP_NOMATCH_INDEX,
555 $this->questionOBJ->getId(),
557 self::FB_TEXT_GAP_EMPTY_INDEX,
564 foreach ($gap->
getItems($this->randomGroup()->dontShuffle()) as $optIndex => $item) {
568 $this->questionOBJ->getId(),
578 $this->questionOBJ->getId(),
580 self::FB_SELECT_GAP_EMPTY_INDEX,
590 $this->questionOBJ->getId(),
592 self::FB_NUMERIC_GAP_VALUE_HIT_INDEX,
600 $this->questionOBJ->getId(),
602 self::FB_NUMERIC_GAP_RANGE_HIT_INDEX,
610 $this->questionOBJ->getId(),
612 self::FB_NUMERIC_GAP_TOO_LOW_INDEX,
619 $this->questionOBJ->getId(),
621 self::FB_NUMERIC_GAP_TOO_HIGH_INDEX,
628 $this->questionOBJ->getId(),
630 self::FB_NUMERIC_GAP_EMPTY_INDEX,
639 parent::duplicateSpecificFeedback($originalQuestionId, $duplicateQuestionId);
644 $res = $this->db->queryF(
645 "SELECT feedback_mode FROM {$this->questionOBJ->getAdditionalTableName()} WHERE question_fi = %s",
650 $row = $this->db->fetchAssoc(
$res);
653 $this->questionOBJ->getAdditionalTableName(),
654 [
'feedback_mode' => [
'text', $row[
'feedback_mode']] ],
655 [
'question_fi' => [
'integer', $targetQuestionId] ]
662 parent::syncSpecificFeedback($originalQuestionId, $duplicateQuestionId);
671 $this->questionOBJ->setFeedbackMode($feedbackMode);
674 $this->questionOBJ->getAdditionalTableName(),
675 [
'feedback_mode' => [
'text', $feedbackMode]],
676 [
'question_fi' => [
'integer', $questionId]]
682 return "feedback_answer_{$gapIndex}";
687 return "feedback_answer_{$gapIndex}_{$answerIndex}";
692 if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
694 $this->questionOBJ->getId(),
715 case self::FB_MODE_GAP_QUESTION:
719 case self::FB_MODE_GAP_ANSWERS:
723 default: $feedbackIds = [];
735 $feedbackIdentifiers->load($this->questionOBJ->getId());
739 foreach ($feedbackIdentifiers as $identifier) {
740 if ($identifier->getAnswerIndex() != self::SINGLE_GAP_FB_ANSWER_INDEX) {
744 $feedbackIds[] = $identifier->getFeedbackId();
756 $feedbackIdentifiers->load($this->questionOBJ->getId());
760 foreach ($feedbackIdentifiers as $identifier) {
761 if ($identifier->getAnswerIndex() == self::SINGLE_GAP_FB_ANSWER_INDEX) {
765 $feedbackIds[] = $identifier->getFeedbackId();
773 if ($this->questionOBJ->getFeedbackMode() === self::FB_MODE_GAP_QUESTION) {
779 if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
780 $all_feedback_content =
'';
781 foreach ($feedback_ids as $feedback_id) {
787 return trim(strip_tags($all_feedback_content)) !==
'';
798 if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
799 foreach ($feedbackIds as $fbId) {
804 $IN_feedbackIds = $this->db->in(
'feedback_id', $feedbackIds,
false,
'integer');
805 $this->db->manipulate(
"DELETE FROM {$this->getSpecificFeedbackTableName()} WHERE {$IN_feedbackIds}");
810 if ($this->questionOBJ->getFeedbackMode() === self::FB_MODE_GAP_QUESTION) {
812 $this->questionOBJ->getId(),
814 self::SINGLE_GAP_FB_ANSWER_INDEX
825 if ($answerValue ===
'') {
826 return self::FB_TEXT_GAP_EMPTY_INDEX;
831 foreach ($items as $answerIndex => $answer) {
834 if ($answer->getAnswertext() == $answerValue) {
839 return self::FB_TEXT_GAP_NOMATCH_INDEX;
842 if ($answerValue !==
'') {
846 return self::FB_SELECT_GAP_EMPTY_INDEX;
850 if ($answerValue ===
'') {
851 return self::FB_NUMERIC_GAP_EMPTY_INDEX;
856 $item = current($gap->
getItems($this->randomGroup()->dontShuffle()));
858 if ($answerValue == $item->getAnswertext()) {
859 return self::FB_NUMERIC_GAP_VALUE_HIT_INDEX;
865 $lowerBound = $math->evaluate($item->getLowerBound());
866 $upperBound = $math->evaluate($item->getUpperBound());
867 $preciseValue = $math->evaluate($item->getAnswertext());
869 $solutionValue = $math->evaluate($answerValue);
871 if ($solutionValue == $preciseValue) {
872 return self::FB_NUMERIC_GAP_VALUE_HIT_INDEX;
873 } elseif ($solutionValue >= $lowerBound && $solutionValue <= $upperBound) {
874 return self::FB_NUMERIC_GAP_RANGE_HIT_INDEX;
875 } elseif ($solutionValue < $lowerBound) {
876 return self::FB_NUMERIC_GAP_TOO_LOW_INDEX;
880 return self::FB_NUMERIC_GAP_TOO_HIGH_INDEX;
889 return $DIC->refinery()->random();
deleteSpecificAnswerFeedbacksByIds(array $feedbackIds)
buildPostVarForFbFieldPerGapQuestion(int $gapIndex)
cleanupSpecificAnswerFeedbacks(string $fbMode)
const FB_NUMERIC_GAP_TOO_HIGH_INDEX
saveFbPropsForSelectGap(ilPropertyFormGUI $form, assClozeGap $gap, int $gapIndex)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getSpecificAnswerFeedbackPageObjectId(int $question_id, int $question_index, int $answer_index)
returns a useable page object id for specific answer feedback page objects for the given question id ...
buildGapFeedbackLabel(int $gapIndex, assClozeGap $gap)
builds an answer option label from given (mixed type) index and answer (overwrites parent method from...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
initFbPropsForSelectGap(ilPropertyFormGUI $form, assClozeGap $gap, int $gapIndex)
initFeedbackFieldsPerGapAnswers(ilPropertyFormGUI $form)
buildSelectGapEmptyFeedbackLabel(int $gapIndex)
syncSpecificFeedbackSetting(int $sourceQuestionId, int $targetQuestionId)
initFeedbackFieldsPerGapQuestion(ilPropertyFormGUI $form)
completeFormPropsForFeedbackModeGapQuestion(ilRadioOption $fbModeOpt)
const FB_NUMERIC_GAP_VALUE_HIT_INDEX
getSpecificAnswerFeedbackPageObjectType()
const CLOZE_TEXT
Cloze question constants.
initFbPropsForNumericGap(ilPropertyFormGUI $form, int $gapIndex, assClozeGap $gap)
saveSpecificFeedbackMode(int $questionId, string $feedbackMode)
saves the given specific feedback mode for the given question id to the db.
completeFbPropsForSelectGap(ilRadioOption $fbModeOpt, assClozeGap $gap, int $gapIndex)
buildTextGapWrongAnswerFeedbackLabel(int $gapIndex)
completeFormPropsForFeedbackModeGapAnswers(ilRadioOption $fbModeOpt)
isSpecificAnswerFeedbackAvailable(int $question_id)
completeFbPropsForNumericGap(ilRadioOption $fbModeOpt, assClozeGap $gap, int $gapIndex)
Class for cloze question gaps.
const FB_NUMERIC_GAP_TOO_LOW_INDEX
saveSpecificFormProperties(ilPropertyFormGUI $form)
initSpecificFormProperties(ilPropertyFormGUI $form)
const FB_NUMERIC_GAP_RANGE_HIT_INDEX
syncSpecificFeedback(int $originalQuestionId, int $duplicateQuestionId)
getSpecificFeedbackContentForFeedbackIds(array $feedback_ids)
getPageObjectXML(string $page_object_type, int $page_object_id)
getItems(Transformation $shuffler, ?int $gap_index=null)
Gets the items of a cloze gap.
buildNumericGapValueHitFeedbackLabel(int $gapIndex)
saveFbPropsForTextGap(ilPropertyFormGUI $form, assClozeGap $gap, int $gapIndex)
buildNumericGapEmptyFeedbackLabel(int $gapIndex)
completeSpecificFormProperties(ilPropertyFormGUI $form)
determineAnswerIndexForAnswerValue(assClozeGap $gap, string $answerValue)
buildSelectGapOptionFeedbackLabel(int $gapIndex, assAnswerCloze $item)
completeFbPropsForTextGap(ilRadioOption $fbModeOpt, assClozeGap $gap, int $gapIndex)
const FB_NUMERIC_GAP_EMPTY_INDEX
buildTextGapGivenAnswerFeedbackLabel(int $gapIndex, assAnswerCloze $item)
fetchFeedbackIdsForGapAnswersMode()
initFbPropsForTextGap(ilPropertyFormGUI $form, assClozeGap $gap, int $gapIndex)
getSpecificAnswerFeedbackTestPresentation(int $question_id, int $question_index, int $answer_index)
returns the html of SPECIFIC feedback for the given question id and answer index for test presentatio...
const FB_TEXT_GAP_NOMATCH_INDEX
getSpecificAnswerFeedbackFormValue(int $gapIndex, int $answerIndex)
getSpecificAnswerFeedbackContent(int $question_id, int $question_index, int $answer_index)
getPageObjectNonEditableValueHTML(string $page_object_type, int $page_object_id)
returns html content to be used as value for non editable value form properties in feedback editing f...
saveFbPropsForNumericGap(ilPropertyFormGUI $form, assClozeGap $gap, int $gapIndex)
buildNumericGapRangeHitFeedbackLabel(int $gapIndex)
const FB_TEXT_GAP_EMPTY_INDEX
constants for answer indexes in case of FB_MODE_GAP_ANSWERS
duplicateSpecificFeedback(int $originalQuestionId, int $duplicateQuestionId)
getAnswertext()
Gets the answer text.
const FB_MODE_GAP_ANSWERS
const FB_SELECT_GAP_EMPTY_INDEX
saveFeedbackFieldsPerGapQuestion(ilPropertyFormGUI $form)
determineTestOutputGapFeedback(int $gap_index, int $answer_index)
buildTextGapEmptyFeedbackLabel(int $gapIndex)
buildNumericGapTooHighFeedbackLabel(int $gapIndex)
ensurePageObjectDeleted(string $page_object_type, int $page_object_id)
buildFeedbackContentFormProperty(string $label, string $post_var, bool $as_non_editable)
builds and returns a form property gui object with the given label and postvar that is addable to pro...
getItem($a_index)
Gets the item with a given index.
saveSpecificAnswerFeedbackContent(int $question_id, int $question_index, int $answer_index, string $feedback_content)
saveFeedbackFieldsPerGapAnswers(ilPropertyFormGUI $form)
fetchFeedbackIdsForGapQuestionMode()
const FB_MODE_GAP_QUESTION
constants for different feedback modes (per gap or per gap-answers/options)
isSaveableInPageObjectEditingMode()
buildPostVarForFbFieldPerGapAnswers(int $gapIndex, int $answerIndex)
const SINGLE_GAP_FB_ANSWER_INDEX
buildNumericGapTooLowFeedbackLabel(int $gapIndex)