123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- <?php // $Id: $
- /* For licensing terms, see /license.txt */
- /**
- * @author Claro Team <cvs@claroline.net>
- * @author Yannick Warnier <yannick.warnier@beeznest.com> - 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 = ' <choiceInteraction responseIdentifier="' . $questionIdent . '" >' . "\n";
- $out .= ' <prompt> ' . $questionStatment . ' </prompt>'. "\n";
- if (is_array($this->answerList)) {
- foreach ($this->answerList as $current_answer) {
- $out .= ' <simpleChoice identifier="answer_' . $current_answer['id'] . '" fixed="false">' . $current_answer['answer'];
- if (isset($current_answer['comment']) && $current_answer['comment'] != '')
- {
- $out .= '<feedbackInline identifier="answer_' . $current_answer['id'] . '">' . $current_answer['comment'] . '</feedbackInline>';
- }
- $out .= '</simpleChoice>'. "\n";
- }
- }
- $out .= ' </choiceInteraction>'. "\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 = ' <responseDeclaration identifier="' . $questionIdent . '" cardinality="' . $cardinality . '" baseType="identifier">' . "\n";
- //Match the correct answers
- $out .= ' <correctResponse>'. "\n";
- if (is_array($this->answerList)) {
- foreach($this->answerList as $current_answer) {
- if ($current_answer['correct'])
- {
- $out .= ' <value>answer_'. $current_answer['id'] .'</value>'. "\n";
- }
- }
- }
- $out .= ' </correctResponse>'. "\n";
- //Add the grading
- $out .= ' <mapping>'. "\n";
- if (is_array($this->answerList)) {
- foreach($this->answerList as $current_answer)
- {
- if (isset($current_answer['grade']))
- {
- $out .= ' <mapEntry mapKey="answer_'. $current_answer['id'] .'" mappedValue="'.$current_answer['grade'].'" />'. "\n";
- }
- }
- }
- $out .= ' </mapping>'. "\n";
- $out .= ' </responseDeclaration>'. "\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.']','<textEntryInteraction responseIdentifier="fill_'.$key.'" expectedLength="'.api_strlen($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 .= '<inlineChoiceInteraction responseIdentifier="fill_'.$answerKey.'" >'. "\n";
- //2- add wrong answer array
- foreach ($this->wrongAnswerList as $choiceKey=>$wrongAnswer)
- {
- $inlineChoiceList .= ' <inlineChoice identifier="choice_w_'.$answerKey.'_'.$choiceKey.'">'.$wrongAnswer.'</inlineChoice>'. "\n";
- }
- //3- add correct answers array
- foreach ($this->answerList as $choiceKey=>$correctAnswer)
- {
- $inlineChoiceList .= ' <inlineChoice identifier="choice_c_'.$answerKey.'_'.$choiceKey.'">'.$correctAnswer.'</inlineChoice>'. "\n";
- }
- //4- finish interaction tag
- $inlineChoiceList .= '</inlineChoiceInteraction>';
- $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 .= ' <responseDeclaration identifier="fill_' . $answerKey . '" cardinality="single" baseType="identifier">' . "\n";
- $out .= ' <correctResponse>'. "\n";
- //if ($this->type==TEXTFIELD_FILL)
- //{
- $out .= ' <value>'.$answer.'</value>'. "\n";
- //}
- /*
- else
- {
- //find correct answer key to apply in manifest and output it
- foreach ($this->answerList as $choiceKey=>$correctAnswer)
- {
- if ($correctAnswer==$answer)
- {
- $out .= ' <value>choice_c_'.$answerKey.'_'.$choiceKey.'</value>'. "\n";
- }
- }
- }
- */
- $out .= ' </correctResponse>'. "\n";
- if (isset($this->gradeList[$answerKey]))
- {
- $out .= ' <mapping>'. "\n";
- $out .= ' <mapEntry mapKey="'.$answer.'" mappedValue="'.$this->gradeList[$answerKey].'"/>'. "\n";
- $out .= ' </mapping>'. "\n";
- }
- $out .= ' </responseDeclaration>'. "\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 .= '<matchInteraction responseIdentifier="' . $questionIdent . '" maxAssociations="'. $maxAssociation .'">'. "\n";
- $out .= $questionStatment;
- //add left column
- $out .= ' <simpleMatchSet>'. "\n";
- if (is_array($this->leftList)) {
- foreach ($this->leftList as $leftKey=>$leftElement)
- {
- $out .= ' <simpleAssociableChoice identifier="left_'.$leftKey.'" >'. $leftElement['answer'] .'</simpleAssociableChoice>'. "\n";
- }
- }
- $out .= ' </simpleMatchSet>'. "\n";
- //add right column
- $out .= ' <simpleMatchSet>'. "\n";
- $i = 0;
- if (is_array($this->rightList)) {
- foreach($this->rightList as $rightKey=>$rightElement)
- {
- $out .= ' <simpleAssociableChoice identifier="right_'.$i.'" >'. $rightElement['answer'] .'</simpleAssociableChoice>'. "\n";
- $i++;
- }
- }
- $out .= ' </simpleMatchSet>'. "\n";
- $out .= '</matchInteraction>'. "\n";
- return $out;
- }
- /**
- *
- */
- function imsExportResponsesDeclaration($questionIdent)
- {
- $this->answerList = $this->getAnswersList(true);
- $out = ' <responseDeclaration identifier="' . $questionIdent . '" cardinality="single" baseType="identifier">' . "\n";
- $out .= ' <correctResponse>' . "\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 .= ' <value>left_' . $leftKey . ' right_'.$i.'</value>'. "\n";
- $gradeArray['left_' . $leftKey . ' right_'.$i] = $leftElement['grade'];
- }
- $i++;
- }
- }
- }
- $out .= ' </correctResponse>'. "\n";
- $out .= ' <mapping>' . "\n";
- if (is_array($gradeArray)) {
- foreach ($gradeArray as $gradeKey=>$grade)
- {
- $out .= ' <mapEntry mapKey="'.$gradeKey.'" mappedValue="'.$grade.'"/>' . "\n";
- }
- }
- $out .= ' </mapping>' . "\n";
- $out .= ' </responseDeclaration>'. "\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 = ' <p>'.$questionStatment.'</p>'."\n";
- $text .= ' <graphicOrderInteraction responseIdentifier="hotspot_'.$questionIdent.'">'."\n";
- $text .= ' <prompt>'.$questionDesc.'</prompt>'."\n";
- $text .= ' <object type="'.$mimetype.'" width="250" height="230" data="'.$questionMedia.'">-</object>'."\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 .= ' <hotspotChoice shape="'.$type.'" coords="'.$coords.'" identifier="'.$key.'"/>'."\n";
- }
- }
- $text .= ' </graphicOrderInteraction>'."\n";
- $out = $text;
- return $out;
- }
- /**
- *
- */
- function imsExportResponsesDeclaration($questionIdent)
- {
- $this->answerList = $this->getAnswersList(true);
- $this->gradeList = $this->getGradesList();
- $out = '';
- $out .= ' <responseDeclaration identifier="hotspot_'.$questionIdent.'" cardinality="ordered" baseType="identifier">' . "\n";
- $out .= ' <correctResponse>'. "\n";
- if (is_array($this->answerList)) {
- foreach ($this->answerList as $answerKey=>$answer)
- {
- $answerKey = $answer['id'];
- $answer = $answer['answer'];
- $out .= ' <value>'.$answerKey.'</value>'. "\n";
- }
- }
- $out .= ' </correctResponse>'. "\n";
- $out .= ' </responseDeclaration>'. "\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 '';
- }
- }
- ?>
|