* @author Yannick Warnier - * updated ImsAnswerHotspot to match QTI norms * * @package chamilo.exercise */ class Ims2Question extends Question { /** * Include the correct answer class and create answer. * * @return Answer */ public function setAnswer() { switch ($this->type) { case MCUA: $answer = new ImsAnswerMultipleChoice($this->id); return $answer; case MCMA: $answer = new ImsAnswerMultipleChoice($this->id); return $answer; case TF: $answer = new ImsAnswerMultipleChoice($this->id); return $answer; case FIB: $answer = new ImsAnswerFillInBlanks($this->id); return $answer; case MATCHING: case MATCHING_DRAGGABLE: $answer = new ImsAnswerMatching($this->id); return $answer; case FREE_ANSWER: $answer = new ImsAnswerFree($this->id); return $answer; case HOT_SPOT: $answer = new ImsAnswerHotspot($this->id); return $answer; default: $answer = null; break; } return $answer; } public function createAnswersForm($form) { return true; } /** * {@inheritdoc} */ public function processAnswersCreation($form, $exercise) { return true; } } /** * Class. * * @package chamilo.exercise */ class ImsAnswerMultipleChoice extends Answer implements ImsAnswerInterface { /** * Return the XML flow for the possible answers. */ public function imsExportResponses($questionIdent, $questionStatment) { // @todo getAnswersList() converts the answers using api_html_entity_decode() $this->answerList = $this->getAnswersList(true); $out = ' '."\n"; $out .= ' '."\n"; if (is_array($this->answerList)) { foreach ($this->answerList as $current_answer) { $out .= ' '; if (isset($current_answer['comment']) && $current_answer['comment'] != '') { $out .= ' '; } $out .= ''."\n"; } } $out .= ' '."\n"; return $out; } /** * Return the XML flow of answer ResponsesDeclaration. */ public function imsExportResponsesDeclaration($questionIdent, Question $question = null) { $this->answerList = $this->getAnswersList(true); $type = $this->getQuestionType(); if ($type == MCMA) { $cardinality = 'multiple'; } else { $cardinality = 'single'; } $out = ' '."\n"; // Match the correct answers. if (is_array($this->answerList)) { $out .= ' '."\n"; foreach ($this->answerList as $current_answer) { if ($current_answer['correct']) { $out .= ' answer_'.$current_answer['id'].''."\n"; } } $out .= ' '."\n"; } // Add the grading if (is_array($this->answerList)) { $out .= ' '."\n"; foreach ($this->answerList as $current_answer) { if (isset($current_answer['grade'])) { $out .= ' '."\n"; } } $out .= ' '."\n"; } $out .= ' '."\n"; return $out; } } /** * Class. * * @package chamilo.exercise */ class ImsAnswerFillInBlanks extends Answer implements ImsAnswerInterface { private $answerList = []; private $gradeList = []; /** * Export the text with missing words. */ public function imsExportResponses($questionIdent, $questionStatment) { $this->answerList = $this->getAnswersList(true); $text = isset($this->answerText) ? $this->answerText : ''; if (is_array($this->answerList)) { foreach ($this->answerList as $key => $answer) { $key = $answer['id']; $answer = $answer['answer']; $len = api_strlen($answer); $text = str_replace('['.$answer.']', '', $text); } } return $text; } public function imsExportResponsesDeclaration($questionIdent, Question $question = null) { $this->answerList = $this->getAnswersList(true); $this->gradeList = $this->getGradesList(); $out = ''; if (is_array($this->answerList)) { foreach ($this->answerList as $answer) { $answerKey = $answer['id']; $answer = $answer['answer']; $out .= ' '."\n"; $out .= ' '."\n"; $out .= ' '."\n"; $out .= ' '."\n"; if (isset($this->gradeList[$answerKey])) { $out .= ' '."\n"; $out .= ' '."\n"; $out .= ' '."\n"; } $out .= ' '."\n"; } } return $out; } } /** * Class. * * @package chamilo.exercise */ class ImsAnswerMatching extends Answer implements ImsAnswerInterface { public $leftList = []; public $rightList = []; private $answerList = []; /** * Export the question part as a matrix-choice, with only one possible answer per line. */ public function imsExportResponses($questionIdent, $questionStatment) { $this->answerList = $this->getAnswersList(true); $maxAssociation = max(count($this->leftList), count($this->rightList)); $out = ''."\n"; $out .= $questionStatment; //add left column $out .= ' '."\n"; if (is_array($this->leftList)) { foreach ($this->leftList as $leftKey => $leftElement) { $out .= ' '."\n"; } } $out .= ' '."\n"; //add right column $out .= ' '."\n"; $i = 0; if (is_array($this->rightList)) { foreach ($this->rightList as $rightKey => $rightElement) { $out .= ' '."\n"; $i++; } } $out .= ' '."\n"; $out .= ''."\n"; return $out; } public function imsExportResponsesDeclaration($questionIdent, Question $question = null) { $this->answerList = $this->getAnswersList(true); $out = ' '."\n"; $out .= ' '."\n"; $gradeArray = []; if (isset($this->leftList) && is_array($this->leftList)) { foreach ($this->leftList as $leftKey => $leftElement) { $i = 0; foreach ($this->rightList as $rightKey => $rightElement) { if (($leftElement['match'] == $rightElement['code'])) { $out .= ' left_'.$leftKey.' right_'.$i.''."\n"; $gradeArray['left_'.$leftKey.' right_'.$i] = $leftElement['grade']; } $i++; } } } $out .= ' '."\n"; if (is_array($gradeArray)) { $out .= ' '."\n"; foreach ($gradeArray as $gradeKey => $grade) { $out .= ' '."\n"; } $out .= ' '."\n"; } $out .= ' '."\n"; return $out; } } /** * Class. * * @package chamilo.exercise */ class ImsAnswerHotspot extends Answer implements ImsAnswerInterface { private $answerList = []; private $gradeList = []; /** * TODO update this to match hot spots instead of copying matching * Export the question part as a matrix-choice, with only one possible answer per line. */ public function imsExportResponses($questionIdent, $questionStatment, $questionDesc = '', $questionMedia = '') { $this->answerList = $this->getAnswersList(true); $mediaFilePath = api_get_course_path().'/document/images/'.$questionMedia; $sysQuestionMediaPath = api_get_path(SYS_COURSE_PATH).$mediaFilePath; $questionMedia = api_get_path(WEB_COURSE_PATH).$mediaFilePath; $mimetype = mime_content_type($sysQuestionMediaPath); if (empty($mimetype)) { $mimetype = 'image/jpeg'; } $text = '

'.$questionStatment.'

'."\n"; $text .= ' '."\n"; $text .= ' '.$questionDesc.''."\n"; $text .= ' -'."\n"; if (is_array($this->answerList)) { foreach ($this->answerList as $key => $answer) { $key = $answer['id']; $answerTxt = $answer['answer']; $len = api_strlen($answerTxt); //coords are transformed according to QTIv2 rules here: http://www.imsproject.org/question/qtiv2p1pd/imsqti_infov2p1pd.html#element10663 $coords = ''; $type = 'default'; switch ($answer['hotspot_type']) { case 'square': $type = 'rect'; $res = []; $coords = preg_match('/^\s*(\d+);(\d+)\|(\d+)\|(\d+)\s*$/', $answer['hotspot_coord'], $res); $coords = $res[1].','.$res[2].','.((int) $res[1] + (int) $res[3]).",".((int) $res[2] + (int) $res[4]); break; case 'circle': $type = 'circle'; $res = []; $coords = preg_match('/^\s*(\d+);(\d+)\|(\d+)\|(\d+)\s*$/', $answer['hotspot_coord'], $res); $coords = $res[1].','.$res[2].','.sqrt(pow(($res[1] - $res[3]), 2) + pow(($res[2] - $res[4]))); break; case 'poly': $type = 'poly'; $coords = str_replace([';', '|'], [',', ','], $answer['hotspot_coord']); break; case 'delineation': $type = 'delineation'; $coords = str_replace([';', '|'], [',', ','], $answer['hotspot_coord']); break; } $text .= ' '."\n"; } } $text .= ' '."\n"; return $text; } public function imsExportResponsesDeclaration($questionIdent, Question $question = null) { $this->answerList = $this->getAnswersList(true); $this->gradeList = $this->getGradesList(); $out = ' '."\n"; if (is_array($this->answerList)) { $out .= ' '."\n"; foreach ($this->answerList as $answerKey => $answer) { $answerKey = $answer['id']; $answer = $answer['answer']; $out .= ''; } $out .= ' '."\n"; } $out .= ' '."\n"; return $out; } } /** * Class. * * @package chamilo.exercise */ class ImsAnswerFree extends Answer implements ImsAnswerInterface { /** * TODO implement * Export the question part as a matrix-choice, with only one possible answer per line. */ public function imsExportResponses( $questionIdent, $questionStatment, $questionDesc = '', $questionMedia = '' ) { $questionDesc = formatExerciseQtiText($questionDesc); return ' '.$questionDesc.' '; } public function imsExportResponsesDeclaration($questionIdent, Question $question = null) { $out = ' '; $out .= ' '.$question->weighting.''; $out .= ' '."\n"; return $out; } }