|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00027 defined('MOODLE_INTERNAL') || die(); 00028 00029 require_once ($CFG->libdir . '/xmlize.php'); 00030 00031 00038 class qformat_examview extends qformat_default { 00039 00040 public $qtypes = array( 00041 'tf' => TRUEFALSE, 00042 'mc' => MULTICHOICE, 00043 'yn' => TRUEFALSE, 00044 'co' => SHORTANSWER, 00045 'ma' => MATCH, 00046 'mtf' => 99, 00047 'nr' => NUMERICAL, 00048 'pr' => 99, 00049 'es' => 99, 00050 'ca' => 99, 00051 'ot' => 99, 00052 'sa' => ESSAY 00053 ); 00054 00055 public $matching_questions = array(); 00056 00057 function provide_import() { 00058 return true; 00059 } 00060 00067 function unxmlise( $xml ) { 00068 // if it's not an array then it's probably just data 00069 if (!is_array($xml)) { 00070 $text = s($xml); 00071 } 00072 else { 00073 // otherwise parse the array 00074 $text = ''; 00075 foreach ($xml as $tag=>$data) { 00076 // if tag is '@' then it's attributes and we don't care 00077 if ($tag!=='@') { 00078 $text = $text . $this->unxmlise( $data ); 00079 } 00080 } 00081 } 00082 00083 // currently we throw the tags we found 00084 $text = strip_tags($text); 00085 return $text; 00086 } 00087 00088 function parse_matching_groups($matching_groups) 00089 { 00090 if (empty($matching_groups)) { 00091 return; 00092 } 00093 foreach($matching_groups as $match_group) { 00094 $newgroup = NULL; 00095 $groupname = trim($match_group['@']['name']); 00096 $questiontext = $this->unxmlise($match_group['#']['text'][0]['#']); 00097 $newgroup->questiontext = trim($questiontext); 00098 $newgroup->subchoices = array(); 00099 $newgroup->subquestions = array(); 00100 $newgroup->subanswers = array(); 00101 $choices = $match_group['#']['choices']['0']['#']; 00102 foreach($choices as $key => $value) { 00103 if (strpos(trim($key),'choice-') !== FALSE) { 00104 $key = strtoupper(trim(str_replace('choice-', '', $key))); 00105 $newgroup->subchoices[$key] = trim($value['0']['#']); 00106 } 00107 } 00108 $this->matching_questions[$groupname] = $newgroup; 00109 } 00110 } 00111 00112 function parse_ma($qrec, $groupname) 00113 { 00114 $match_group = $this->matching_questions[$groupname]; 00115 $phrase = trim($this->unxmlise($qrec['text']['0']['#'])); 00116 $answer = trim($this->unxmlise($qrec['answer']['0']['#'])); 00117 $answer = strip_tags( $answer ); 00118 $match_group->subquestions[] = $phrase; 00119 $match_group->subanswers[] = $match_group->subchoices[$answer]; 00120 $this->matching_questions[$groupname] = $match_group; 00121 return NULL; 00122 } 00123 00124 function process_matches(&$questions) 00125 { 00126 if (empty($this->matching_questions)) { 00127 return; 00128 } 00129 foreach($this->matching_questions as $match_group) { 00130 $question = $this->defaultquestion(); 00131 $htmltext = s($match_group->questiontext); 00132 $question->questiontext = $htmltext; 00133 $question->name = $question->questiontext; 00134 $question->qtype = MATCH; 00135 $question->subquestions = array(); 00136 $question->subanswers = array(); 00137 foreach($match_group->subquestions as $key => $value) { 00138 $htmltext = s($value); 00139 $question->subquestions[] = $htmltext; 00140 00141 $htmltext = s($match_group->subanswers[$key]); 00142 $question->subanswers[] = $htmltext; 00143 } 00144 $questions[] = $question; 00145 } 00146 } 00147 00148 function cleanUnicode($text) { 00149 return str_replace('’', "'", $text); 00150 } 00151 00152 function readquestions($lines) { 00156 00157 $questions = array(); 00158 $currentquestion = array(); 00159 00160 $text = implode($lines, ' '); 00161 $text = $this->cleanUnicode($text); 00162 00163 $xml = xmlize($text, 0); 00164 if (!empty($xml['examview']['#']['matching-group'])) { 00165 $this->parse_matching_groups($xml['examview']['#']['matching-group']); 00166 } 00167 00168 $questionNode = $xml['examview']['#']['question']; 00169 foreach($questionNode as $currentquestion) { 00170 if ($question = $this->readquestion($currentquestion)) { 00171 $questions[] = $question; 00172 } 00173 } 00174 00175 $this->process_matches($questions); 00176 return $questions; 00177 } 00178 // end readquestions 00179 00180 function readquestion($qrec) 00181 { 00182 00183 $type = trim($qrec['@']['type']); 00184 $question = $this->defaultquestion(); 00185 if (array_key_exists($type, $this->qtypes)) { 00186 $question->qtype = $this->qtypes[$type]; 00187 } 00188 else { 00189 $question->qtype = null; 00190 } 00191 $question->single = 1; 00192 // Only one answer is allowed 00193 $htmltext = $this->unxmlise($qrec['#']['text'][0]['#']); 00194 $question->questiontext = $htmltext; 00195 $question->name = shorten_text( $question->questiontext, 250 ); 00196 00197 switch ($question->qtype) { 00198 case MULTICHOICE: 00199 $question = $this->parse_mc($qrec['#'], $question); 00200 break; 00201 case MATCH: 00202 $groupname = trim($qrec['@']['group']); 00203 $question = $this->parse_ma($qrec['#'], $groupname); 00204 break; 00205 case TRUEFALSE: 00206 $question = $this->parse_tf_yn($qrec['#'], $question); 00207 break; 00208 case SHORTANSWER: 00209 $question = $this->parse_co($qrec['#'], $question); 00210 break; 00211 case ESSAY: 00212 $question = $this->parse_sa($qrec['#'], $question); 00213 break; 00214 case NUMERICAL: 00215 $question = $this->parse_nr($qrec['#'], $question); 00216 break; 00217 break; 00218 default: 00219 print("<p>Question type ".$type." import not supported for ".$question->questiontext."<p>"); 00220 $question = NULL; 00221 } 00222 // end switch ($question->qtype) 00223 00224 return $question; 00225 } 00226 // end readquestion 00227 00228 function parse_tf_yn($qrec, $question) 00229 { 00230 $choices = array('T' => 1, 'Y' => 1, 'F' => 0, 'N' => 0 ); 00231 $answer = trim($qrec['answer'][0]['#']); 00232 $question->answer = $choices[$answer]; 00233 $question->correctanswer = $question->answer; 00234 if ($question->answer == 1) { 00235 $question->feedbacktrue = 'Correct'; 00236 $question->feedbackfalse = 'Incorrect'; 00237 } else { 00238 $question->feedbacktrue = 'Incorrect'; 00239 $question->feedbackfalse = 'Correct'; 00240 } 00241 return $question; 00242 } 00243 00244 function parse_mc($qrec, $question) 00245 { 00246 $answer = 'choice-'.strtolower(trim($qrec['answer'][0]['#'])); 00247 00248 $choices = $qrec['choices'][0]['#']; 00249 foreach($choices as $key => $value) { 00250 if (strpos(trim($key),'choice-') !== FALSE) { 00251 00252 $question->answer[$key] = s($this->unxmlise($value[0]['#'])); 00253 if (strcmp($key, $answer) == 0) { 00254 $question->fraction[$key] = 1; 00255 $question->feedback[$key] = 'Correct'; 00256 } else { 00257 $question->fraction[$key] = 0; 00258 $question->feedback[$key] = 'Incorrect'; 00259 } 00260 } 00261 } 00262 return $question; 00263 } 00264 00265 function parse_co($qrec, $question) 00266 { 00267 $question->usecase = 0; 00268 $answer = trim($this->unxmlise($qrec['answer'][0]['#'])); 00269 $answer = strip_tags( $answer ); 00270 $answers = explode("\n",$answer); 00271 00272 foreach($answers as $key => $value) { 00273 $value = trim($value); 00274 if (strlen($value) > 0) { 00275 $question->answer[$key] = $value; 00276 $question->fraction[$key] = 1; 00277 $question->feedback[$key] = "Correct"; 00278 } 00279 } 00280 return $question; 00281 } 00282 00283 function parse_sa($qrec, $question) { 00284 $feedback = trim($this->unxmlise($qrec['answer'][0]['#'])); 00285 $question->feedback = $feedback; 00286 $question->fraction = 0; 00287 return $question; 00288 } 00289 00290 function parse_nr($qrec, $question) 00291 { 00292 $answer = trim($this->unxmlise($qrec['answer'][0]['#'])); 00293 $answer = strip_tags( $answer ); 00294 $answers = explode("\n",$answer); 00295 00296 foreach($answers as $key => $value) { 00297 $value = trim($value); 00298 if (is_numeric($value)) { 00299 $errormargin = 0; 00300 $question->answer[$key] = $value; 00301 $question->fraction[$key] = 1; 00302 $question->feedback[$key] = "Correct"; 00303 $question->min[$key] = $question->answer[$key] - $errormargin; 00304 $question->max[$key] = $question->answer[$key] + $errormargin; 00305 } 00306 } 00307 return $question; 00308 } 00309 00310 } 00311 // end class 00312 00313