* @author Yannick Warnier * @package chamilo.exercise */ /** * Code */ if ( count( get_included_files() ) == 1 ) die( '---' ); require_once '../../exercise.class.php'; require_once '../../question.class.php'; require_once '../../answer.class.php'; require_once '../../unique_answer.class.php'; require_once '../../multiple_answer.class.php'; require_once '../../fill_blanks.class.php'; require_once '../../freeanswer.class.php'; require_once '../../hotspot.class.php'; require_once '../../matching.class.php'; require_once '../../hotspot.class.php'; /** * * @package chamilo.exercise */ class ImsQuestion extends Question { /** * Include the correct answer class and create answer */ function setAnswer() { switch($this->type) { case MCUA : $this->answer = new ImsAnswerMultipleChoice($this->id, false); break; case MCMA : $this->answer = new ImsAnswerMultipleChoice($this->id, true); break; case TF : $this->answer = new ImsAnswerTrueFalse($this->id); break; case FIB : $this->answer = new ImsAnswerFillInBlanks($this->id); break; case MATCHING : $this->answer = new ImsAnswerMatching($this->id); break; default : $this->answer = null; break; } return true; } /** * allow to import the question * * @param questionArray is an array that must contain all the information needed to build the question * @author Guillaume Lederer */ function import($questionArray, $exerciseTempPath) { //import answers $this->answer->import($questionArray); //import attached file, if any if (isset($questionArray['attached_file_url'])) { $file= array(); $file['name'] = $questionArray['attached_file_url']; $file['tmp_name'] = $exerciseTempPath.$file['name']; $this->setAttachment($file); } } } /** * * @package chamilo.exercise */ class ImsAnswerMultipleChoice extends answerMultipleChoice { /** * Return the XML flow for the possible answers. * That's one , containing several * * @author Amand Tihon */ function imsExportResponses($questionIdent) { // Opening of the response block. if( $this->multipleAnswer ) { $out = '' . "\n" . '' . "\n"; } else { $out = '' . "\n"; } // Loop over answers foreach( $this->answerList as $answer ) { $responseIdent = $questionIdent . "_A_" . $answer['id']; $out.= ' '.(!$this->multipleAnswer ? '':'').'' . "\n" . ' ' . "\n" . ' '.(!$this->multipleAnswer ? '':'').'' . "\n"; } $out.= "\n"; return $out; } /** * Return the XML flow of answer processing : a succession of . * * @author Amand Tihon */ function imsExportProcessing($questionIdent) { $out = ''; foreach( $this->answerList as $answer ) { $responseIdent = $questionIdent . "_A_" . $answer['id']; $feedbackIdent = $questionIdent . "_F_" . $answer['id']; $conditionIdent = $questionIdent . "_C_" . $answer['id']; if( $this->multipleAnswer ) { $out .= '' . "\n" . ' ' . $responseIdent . '' . "\n"; } else { $out .= '' . "\n" . ' ' . $responseIdent . '' . "\n"; } $out .= " \n" . ' ' . $answer['grade'] . "\n"; // Only add references for actually existing comments/feedbacks. if( !empty($answer['comment']) ) { $out .= ' ' . "\n"; } $out .= "\n"; } return $out; } /** * Export the feedback (comments to selected answers) to IMS/QTI * * @author Amand Tihon */ function imsExportFeedback($questionIdent) { $out = ""; foreach( $this->answerList as $answer ) { if( !empty($answer['comment']) ) { $feedbackIdent = $questionIdent . "_F_" . $answer['id']; $out.= '' . "\n" . ' \n" . "\n"; } } return $out; } /** * allow to import the answers, feedbacks, and grades of a question * @param questionArray is an array that must contain all the information needed to build the question * @author Guillaume Lederer */ function import($questionArray) { $answerArray = $questionArray['answer']; $this->answerList = array(); //re-initialize answer object content foreach ($answerArray as $key => $answer) { if (!isset($answer['feedback'])) $answer['feedback'] = ""; if (!isset($questionArray['weighting'][$key])) { if (isset($questionArray['default_weighting'])) { $grade = $questionArray['default_weighting']; } else { $grade = 0; } } else { $grade = $questionArray['weighting'][$key]; } if (in_array($key,$questionArray['correct_answers'])) $is_correct = true; else $is_correct = false; $addedAnswer = array( 'answer' => $answer['value'], 'correct' => $is_correct, 'grade' => $grade, 'comment' => $answer['feedback'], ); $this->answerList[] = $addedAnswer; } } } /** * * @package chamilo.exercise */ class ImsAnswerTrueFalse extends answerTrueFalse { /** * Return the XML flow for the possible answers. * That's one , containing several * * @author Amand Tihon */ function imsExportResponses($questionIdent) { // Opening of the response block. $out = '' . "\n"; // true $response_ident = $questionIdent . '_A_true'; $out .= ' ' . "\n" . ' ' . "\n" . ' ' . "\n"; // false $response_ident = $questionIdent . '_A_false'; $out .= ' ' . "\n" . ' ' . "\n" . ' ' . "\n"; $out .= '' . "\n"; return $out; } /** * Return the XML flow of answer processing : a succession of . * * @author Amand Tihon */ function imsExportProcessing($questionIdent) { $out = ''; // true $response_ident = $questionIdent. '_A_true'; $feedback_ident = $questionIdent . '_F_true'; $condition_ident = $questionIdent . '_C_true'; $out .= '' . "\n" . ' ' . $response_ident . '' . "\n" . ' ' . "\n" . ' ' . $this->trueGrade . '' . "\n"; // Only add references for actually existing comments/feedbacks. if( !empty($this->trueFeedback) ) { $out.= ' ' . "\n"; } $out .= '' . "\n"; // false $response_ident = $questionIdent. '_A_false'; $feedback_ident = $questionIdent . '_F_false'; $condition_ident = $questionIdent . '_C_false'; $out .= '' . "\n" . ' ' . $response_ident . '' . "\n" . ' ' . "\n" . ' ' . $this->falseGrade . '' . "\n"; // Only add references for actually existing comments/feedbacks. if( !empty($this->falseFeedback) ) { $out.= ' ' . "\n"; } $out .= '' . "\n"; return $out; } /** * Export the feedback (comments to selected answers) to IMS/QTI * * @author Amand Tihon */ function imsExportFeedback($questionIdent) { $out = ""; if( !empty($this->trueFeedback) ) { $feedback_ident = $questionIdent . '_F_true'; $out.= '' . "\n" . ' trueFeedback . "]]>\n" . "\n"; } if( !empty($this->falseFeedback) ) { $feedback_ident = $questionIdent . '_F_false'; $out.= '' . "\n" . ' falseFeedback . "]]>\n" . "\n"; } return $out; } } /** * * @package chamilo.exercise */ class ImsAnswerFillInBlanks extends answerFillInBlanks { /** * Export the text with missing words. * * As a side effect, it stores two lists in the class : * the missing words and their respective weightings. * * @author Amand Tihon */ function imsExportResponses($questionIdent) { global $charset; $out = "\n"; $responsePart = explode(']', $this->answer); $i = 0; // Used for the reference generation. foreach($responsePart as $part) { $response_ident = $questionIdent . "_A_" . $i; if( strpos($part,'[') !== false ) { list($rawText, $blank) = explode('[', $part); } else { $rawText = $part; $blank = ""; } if ($rawText!="") { $out.=" \n"; } if ($blank!="") { $out.= ' ' . "\n" . ' ' . "\n" . ' ' . "\n" . " \n" . " \n"; } $i++; } $out.="\n"; return $out; } /** * Exports the response processing. * * It uses the two lists build by export_responses(). This implies that export_responses MUST * be called before. * * @author Amand Tihon */ function imsExportProcessing($questionIdent) { $out = ""; $answerCount = count($this->answerList); for( $i = 0; $i < $answerCount ; $i++ ) { $response_ident = $questionIdent . "_A_" . $i; $out.= ' ' . "\n" . ' answerList[$i] . ']]>' . "\n" . ' ' . $this->gradeList[$i] . "\n" . " \n"; } return $out; } /** * Export the feedback (comments to selected answers) to IMS/QTI * * @author Amand Tihon */ function imsExportFeedback($questionIdent) { // no feedback in this question type return ''; } /** * allow to import the answers, feedbacks, and grades of a question * * @param questionArray is an array that must contain all the information needed to build the question * @author Guillaume Lederer */ function import($questionArray) { $answerArray = $questionArray['answer']; $this->answerText = str_replace ("\n","",$questionArray['response_text']); if ($questionArray['subtype'] == "TEXTFIELD_FILL") $this->type = TEXTFIELD_FILL; if ($questionArray['subtype'] == "LISTBOX_FILL") { $this->wrongAnswerList = $questionArray['wrong_answers']; $this->type = LISTBOX_FILL; } //build correct_answsers array if (isset($questionArray['weighting'])) { $this->gradeList = $questionArray['weighting']; } } } /** * * @package chamilo.exercise */ class ImsAnswerMatching extends answerMatching { /** * Export the question part as a matrix-choice, with only one possible answer per line. * @author Amand Tihon */ function imsExportResponses($questionIdent) { $out = ""; // Now, loop again, finding questions (rows) foreach( $this->leftList as $leftElt ) { $responseIdent = $questionIdent . "_A_" . $leftElt['code']; $out.= '' . "\n" . '\n" . ' ' . "\n"; foreach( $this->rightList as $rightElt ) { $out.= ' ' . "\n" . " \n" . " \n"; } $out.= "\n"; } return $out; } /** * Export the response processing part * @author Amand Tihon */ function imsExportProcessing($questionIdent) { $out = ""; foreach( $this->leftList as $leftElt ) { $responseIdent = $questionIdent . "_A_" . $leftElt['code']; $out.= ' ' . "\n" . ' ' . $leftElt['match'] . "\n" . ' ' . $leftElt['grade'] . "\n" . " \n"; } return $out; } /** * Export the feedback (comments to selected answers) to IMS/QTI * * @author Amand Tihon */ function imsExportFeedback($questionIdent) { // no feedback in this question type return ''; } /** * allow to import the answers, feedbacks, and grades of a question * * @param questionArray is an array that must contain all the information needed to build the question * @author Guillaume Lederer */ function import($questionArray) { $answerArray = $questionArray['answer']; //This tick to remove examples in the answers!!!! $this->leftList = array(); $this->rightList = array(); //find right and left column $right_column = array_pop($answerArray); $left_column = array_pop($answerArray); //1- build answers foreach ($right_column as $right_key => $right_element) { $code = $this->addRight($right_element); foreach ($left_column as $left_key => $left_element) { $matched_pattern = $left_key." ".$right_key; $matched_pattern_inverted = $right_key." ".$left_key; if (in_array($matched_pattern, $questionArray['correct_answers']) || in_array($matched_pattern_inverted, $questionArray['correct_answers'])) { if (isset($questionArray['weighting'][$matched_pattern])) { $grade = $questionArray['weighting'][$matched_pattern]; } else { $grade = 0; } $this->addLeft($left_element, $code, $grade); } } } } } ?>