* @author Yannick Warnier - updated ImsAnswerHotspot to match QTI norms * @package chamilo.exercise */ /** * Code */ if ( count( get_included_files() ) == 1 ) die( '---' ); if (!function_exists('mime_content_type')) { function mime_content_type($filename) { return DocumentManager::file_get_mime_type((string)$filename); } } require_once(api_get_path(SYS_CODE_PATH).'/exercice/answer.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/exercise.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/question.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/hotspot.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/unique_answer.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/multiple_answer.class.php'); //require_once(api_get_path(SYS_CODE_PATH).'/exercice/multiple_answer_combination.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/matching.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/freeanswer.class.php'); require_once(api_get_path(SYS_CODE_PATH).'/exercice/fill_blanks.class.php'); //include_once $path . '/../../lib/answer_multiplechoice.class.php'; //include_once $path . '/../../lib/answer_truefalse.class.php'; //include_once $path . '/../../lib/answer_fib.class.php'; //include_once $path . '/../../lib/answer_matching.class.php'; /** * * @package chamilo.exercise */ class Ims2Question extends Question { /** * Include the correct answer class and create answer */ 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 : $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; } function createAnswersForm($form) { return true; } function processAnswersCreation($form) { return true; } } /** * Class * @package chamilo.exercise */ class ImsAnswerMultipleChoice extends Answer { /** * Return the XML flow for the possible answers. * */ function imsExportResponses($questionIdent, $questionStatment) { $this->answerList = $this->getAnswersList(true); $out = ' ' . "\n"; $out .= ' ' . $questionStatment . ' '. "\n"; if (is_array($this->answerList)) { foreach ($this->answerList as $current_answer) { $out .= ' ' . $current_answer['answer']; if (isset($current_answer['comment']) && $current_answer['comment'] != '') { $out .= '' . $current_answer['comment'] . ''; } $out .= ''. "\n"; } } $out .= ' '. "\n"; return $out; } /** * Return the XML flow of answer ResponsesDeclaration * */ function imsExportResponsesDeclaration($questionIdent) { $this->answerList = $this->getAnswersList(true); $type = $this->getQuestionType(); if ($type == MCMA) $cardinality = 'multiple'; else $cardinality = 'single'; $out = ' ' . "\n"; //Match the correct answers $out .= ' '. "\n"; if (is_array($this->answerList)) { foreach($this->answerList as $current_answer) { if ($current_answer['correct']) { $out .= ' answer_'. $current_answer['id'] .''. "\n"; } } } $out .= ' '. "\n"; //Add the grading $out .= ' '. "\n"; if (is_array($this->answerList)) { 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 { /** * Export the text with missing words. * * */ function imsExportResponses($questionIdent, $questionStatment) { global $charset; $this->answerList = $this->getAnswersList(true); //switch ($this->type) //{ // case TEXTFIELD_FILL : // { $text = ''; $text .= $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); } } $out = $text; // } // break; /* case LISTBOX_FILL : { $text = $this->answerText; foreach ($this->answerList as $answerKey=>$answer) { //build inlinechoice list $inlineChoiceList = ''; //1-start interaction tag $inlineChoiceList .= ''. "\n"; //2- add wrong answer array foreach ($this->wrongAnswerList as $choiceKey=>$wrongAnswer) { $inlineChoiceList .= ' '.$wrongAnswer.''. "\n"; } //3- add correct answers array foreach ($this->answerList as $choiceKey=>$correctAnswer) { $inlineChoiceList .= ' '.$correctAnswer.''. "\n"; } //4- finish interaction tag $inlineChoiceList .= ''; $text = str_replace('['.$answer.']',$inlineChoiceList, $text); } $out = $text; } break; */ //} return $out; } /** * */ function imsExportResponsesDeclaration($questionIdent) { $this->answerList = $this->getAnswersList(true); $this->gradeList = $this->getGradesList(); $out = ''; if (is_array($this->answerList)) { foreach ($this->answerList as $answerKey=>$answer) { $answerKey = $answer['id']; $answer = $answer['answer']; $out .= ' ' . "\n"; $out .= ' '. "\n"; //if ($this->type==TEXTFIELD_FILL) //{ $out .= ' '.$answer.''. "\n"; //} /* else { //find correct answer key to apply in manifest and output it foreach ($this->answerList as $choiceKey=>$correctAnswer) { if ($correctAnswer==$answer) { $out .= ' choice_c_'.$answerKey.'_'.$choiceKey.''. "\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 { /** * Export the question part as a matrix-choice, with only one possible answer per line. */ function imsExportResponses($questionIdent, $questionStatment) { $this->answerList = $this->getAnswersList(true); $maxAssociation = max(count($this->leftList), count($this->rightList)); $out = ""; $out .= ''. "\n"; $out .= $questionStatment; //add left column $out .= ' '. "\n"; if (is_array($this->leftList)) { foreach ($this->leftList as $leftKey=>$leftElement) { $out .= ' '. $leftElement['answer'] .''. "\n"; } } $out .= ' '. "\n"; //add right column $out .= ' '. "\n"; $i = 0; if (is_array($this->rightList)) { foreach($this->rightList as $rightKey=>$rightElement) { $out .= ' '. $rightElement['answer'] .''. "\n"; $i++; } } $out .= ' '. "\n"; $out .= ''. "\n"; return $out; } /** * */ function imsExportResponsesDeclaration($questionIdent) { $this->answerList = $this->getAnswersList(true); $out = ' ' . "\n"; $out .= ' ' . "\n"; $gradeArray = array(); if (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"; $out .= ' ' . "\n"; if (is_array($gradeArray)) { foreach ($gradeArray as $gradeKey=>$grade) { $out .= ' ' . "\n"; } } $out .= ' ' . "\n"; $out .= ' '. "\n"; return $out; } } /** * Class * @package chamilo.exercise */ class ImsAnswerHotspot extends Answer { /** * TODO update this to match hotspots instead of copying matching * Export the question part as a matrix-choice, with only one possible answer per line. */ function imsExportResponses($questionIdent, $questionStatment, $questionDesc='', $questionMedia='') { global $charset; $this->answerList = $this->getAnswersList(true); $questionMedia = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document/images/'.$questionMedia; $mimetype = mime_content_type($questionMedia); 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 = array(); $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 = array(); $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(array(';','|'),array(',',','),$answer['hotspot_coord']); break; case 'delineation' : $type = 'delineation'; $coords = str_replace(array(';','|'),array(',',','),$answer['hotspot_coord']); break; } $text .= ' '."\n"; } } $text .= ' '."\n"; $out = $text; return $out; } /** * */ function imsExportResponsesDeclaration($questionIdent) { $this->answerList = $this->getAnswersList(true); $this->gradeList = $this->getGradesList(); $out = ''; $out .= ' ' . "\n"; $out .= ' '. "\n"; if (is_array($this->answerList)) { foreach ($this->answerList as $answerKey=>$answer) { $answerKey = $answer['id']; $answer = $answer['answer']; $out .= ' '.$answerKey.''. "\n"; } } $out .= ' '. "\n"; $out .= ' '. "\n"; return $out; } } /** * Class * @package chamilo.exercise */ class ImsAnswerFree extends Answer { /** * TODO implement * Export the question part as a matrix-choice, with only one possible answer per line. */ function imsExportResponses($questionIdent, $questionStatment, $questionDesc='', $questionMedia='') { return ''; } /** * */ function imsExportResponsesDeclaration($questionIdent) { return ''; } } ?>