|
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 00034 function unhtmlentities($string){ 00035 $search = array ("'<script[?>]*?>.*?</script>'si", // remove javascript 00036 "'<[\/\!]*?[^<?>]*?>'si", // remove HTML tags 00037 "'([\r\n])[\s]+'", // remove spaces 00038 "'&(quot|#34);'i", // remove HTML entites 00039 "'&(amp|#38);'i", 00040 "'&(lt|#60);'i", 00041 "'&(gt|#62);'i", 00042 "'&(nbsp|#160);'i", 00043 "'&(iexcl|#161);'i", 00044 "'&(cent|#162);'i", 00045 "'&(pound|#163);'i", 00046 "'&(copy|#169);'i", 00047 "'&#(\d+);'e"); // Evaluate like PHP 00048 $replace = array ("", 00049 "", 00050 "\\1", 00051 "\"", 00052 "&", 00053 "<", 00054 "?>", 00055 " ", 00056 chr(161), 00057 chr(162), 00058 chr(163), 00059 chr(169), 00060 "chr(\\1)"); 00061 return preg_replace ($search, $replace, $string); 00062 } 00063 00068 function qformat_webct_convert_formula($formula) { 00069 00070 // Remove empty space, as it would cause problems otherwise: 00071 $formula = str_replace(' ', '', $formula); 00072 00073 // Remove paranthesis after e,E and *10**: 00074 while (preg_match('~[0-9.](e|E|\\*10\\*\\*)\\([+-]?[0-9]+\\)~', $formula, $regs)) { 00075 $formula = str_replace( 00076 $regs[0], preg_replace('/[)(]/', '', $regs[0]), $formula); 00077 } 00078 00079 // Replace *10** with e where possible 00080 while (preg_match('~(^[+-]?|[^eE][+-]|[^0-9eE+-])[0-9.]+\\*10\\*\\*[+-]?[0-9]+([^0-9.eE]|$)~', 00081 $formula, $regs)) { 00082 $formula = str_replace( 00083 $regs[0], str_replace('*10**', 'e', $regs[0]), $formula); 00084 } 00085 00086 // Replace other 10** with 1e where possible 00087 while (preg_match('~(^|[^0-9.eE])10\\*\\*[+-]?[0-9]+([^0-9.eE]|$)~', $formula, $regs)) { 00088 $formula = str_replace( 00089 $regs[0], str_replace('10**', '1e', $regs[0]), $formula); 00090 } 00091 00092 // Replace all other base**exp with the PHP equivalent function pow(base,exp) 00093 // (Pretty tricky to exchange an operator with a function) 00094 while (2 == count($splits = explode('**', $formula, 2))) { 00095 00096 // Find $base 00097 if (preg_match('~^(.*[^0-9.eE])?(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?|\\{[^}]*\\})$~', 00098 $splits[0], $regs)) { 00099 // The simple cases 00100 $base = $regs[2]; 00101 $splits[0] = $regs[1]; 00102 00103 } else if (preg_match('~\\)$~', $splits[0])) { 00104 // Find the start of this parenthesis 00105 $deep = 1; 00106 for ($i = 1 ; $deep ; ++$i) { 00107 if (!preg_match('~^(.*[^[:alnum:]_])?([[:alnum:]_]*([)(])([^)(]*[)(]){'.$i.'})$~', 00108 $splits[0], $regs)) { 00109 print_error("parenthesisinproperstart", 'question', '', $splits[0]); 00110 } 00111 if ('(' == $regs[3]) { 00112 --$deep; 00113 } else if (')' == $regs[3]) { 00114 ++$deep; 00115 } else { 00116 print_error('impossiblechar', 'question', '', $regs[3]); 00117 } 00118 } 00119 $base = $regs[2]; 00120 $splits[0] = $regs[1]; 00121 00122 } else { 00123 print_error('badbase', 'question', '', $splits[0]); 00124 } 00125 00126 // Find $exp (similar to above but a little easier) 00127 if (preg_match('~^([+-]?(\\{[^}]\\}|([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?))(.*)~', 00128 $splits[1], $regs)) { 00129 // The simple case 00130 $exp = $regs[1]; 00131 $splits[1] = $regs[6]; 00132 00133 } else if (preg_match('~^[+-]?[[:alnum:]_]*\\(~', $splits[1])) { 00134 // Find the end of the parenthesis 00135 $deep = 1; 00136 for ($i = 1 ; $deep ; ++$i) { 00137 if (!preg_match('~^([+-]?[[:alnum:]_]*([)(][^)(]*){'.$i.'}([)(]))(.*)~', 00138 $splits[1], $regs)) { 00139 print_error("parenthesisinproperclose", 'question', '', $splits[1]); 00140 } 00141 if (')' == $regs[3]) { 00142 --$deep; 00143 } else if ('(' == $regs[3]) { 00144 ++$deep; 00145 } else { 00146 print_error("impossiblechar", 'question'); 00147 } 00148 } 00149 $exp = $regs[1]; 00150 $splits[1] = $regs[4]; 00151 } 00152 00153 // Replace it! 00154 $formula = "$splits[0]pow($base,$exp)$splits[1]"; 00155 } 00156 00157 // Nothing more is known to need to be converted 00158 00159 return $formula; 00160 } 00161 00162 00169 class qformat_webct extends qformat_default { 00170 00171 function provide_import() { 00172 return true; 00173 } 00174 00175 function readquestions ($lines) { 00176 $webctnumberregex = 00177 '[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)((e|E|\\*10\\*\\*)([+-]?[0-9]+|\\([+-]?[0-9]+\\)))?'; 00178 00179 $questions = array(); 00180 $errors = array(); 00181 $warnings = array(); 00182 $webct_options = array(); 00183 00184 $ignore_rest_of_question = FALSE; 00185 00186 $nLineCounter = 0; 00187 $nQuestionStartLine = 0; 00188 $bIsHTMLText = FALSE; 00189 $lines[] = ":EOF:"; // for an easiest processing of the last line 00190 // $question = $this->defaultquestion(); 00191 00192 foreach ($lines as $line) { 00193 $nLineCounter++; 00194 $line = iconv("Windows-1252","UTF-8",$line); 00195 // Processing multiples lines strings 00196 00197 if (isset($questiontext) and is_string($questiontext)) { 00198 if (preg_match("~^:~",$line)) { 00199 $question->questiontext = trim($questiontext); 00200 unset($questiontext); 00201 } 00202 else { 00203 $questiontext .= str_replace('\:', ':', $line); 00204 continue; 00205 } 00206 } 00207 00208 if (isset($answertext) and is_string($answertext)) { 00209 if (preg_match("~^:~",$line)) { 00210 $answertext = trim($answertext); 00211 $question->answer[$currentchoice] = $answertext; 00212 $question->subanswers[$currentchoice] = $answertext; 00213 unset($answertext); 00214 } 00215 else { 00216 $answertext .= str_replace('\:', ':', $line); 00217 continue; 00218 } 00219 } 00220 00221 if (isset($responsetext) and is_string($responsetext)) { 00222 if (preg_match("~^:~",$line)) { 00223 $question->subquestions[$currentchoice] = trim($responsetext); 00224 unset($responsetext); 00225 } 00226 else { 00227 $responsetext .= str_replace('\:', ':', $line); 00228 continue; 00229 } 00230 } 00231 00232 if (isset($feedbacktext) and is_string($feedbacktext)) { 00233 if (preg_match("~^:~",$line)) { 00234 $question->feedback[$currentchoice] = trim($feedbacktext); 00235 unset($feedbacktext); 00236 } 00237 else { 00238 $feedbacktext .= str_replace('\:', ':', $line); 00239 continue; 00240 } 00241 } 00242 00243 if (isset($generalfeedbacktext) and is_string($generalfeedbacktext)) { 00244 if (preg_match("~^:~",$line)) { 00245 $question->tempgeneralfeedback= trim($generalfeedbacktext); 00246 unset($generalfeedbacktext); 00247 } 00248 else { 00249 $generalfeedbacktext .= str_replace('\:', ':', $line); 00250 continue; 00251 } 00252 } 00253 00254 $line = trim($line); 00255 00256 if (preg_match("~^:(TYPE|EOF):~i",$line)) { 00257 // New Question or End of File 00258 if (isset($question)) { // if previous question exists, complete, check and save it 00259 00260 // Setup default value of missing fields 00261 if (!isset($question->name)) { 00262 $question->name = $question->questiontext; 00263 } 00264 if (strlen($question->name) > 255) { 00265 $question->name = substr($question->name,0,250)."..."; 00266 $warnings[] = get_string("questionnametoolong", "qformat_webct", $nQuestionStartLine); 00267 } 00268 if (!isset($question->defaultmark)) { 00269 $question->defaultmark = 1; 00270 } 00271 if (!isset($question->image)) { 00272 $question->image = ""; 00273 } 00274 00275 // Perform sanity checks 00276 $QuestionOK = TRUE; 00277 if (strlen($question->questiontext) == 0) { 00278 $warnings[] = get_string("missingquestion", "qformat_webct", $nQuestionStartLine); 00279 $QuestionOK = FALSE; 00280 } 00281 if (sizeof($question->answer) < 1) { // a question must have at least 1 answer 00282 $errors[] = get_string("missinganswer", "qformat_webct", $nQuestionStartLine); 00283 $QuestionOK = FALSE; 00284 } 00285 else { 00286 // Create empty feedback array 00287 foreach ($question->answer as $key => $dataanswer) { 00288 if(!isset( $question->feedback[$key])){ 00289 $question->feedback[$key] = ''; 00290 } 00291 } 00292 // this tempgeneralfeedback allows the code to work with versions from 1.6 to 1.9 00293 // when question->generalfeedback is undefined, the webct feedback is added to each answer feedback 00294 if (isset($question->tempgeneralfeedback)){ 00295 if (isset($question->generalfeedback)) { 00296 $question->generalfeedback = $question->tempgeneralfeedback; 00297 } else { 00298 foreach ($question->answer as $key => $dataanswer) { 00299 if ($question->tempgeneralfeedback !=''){ 00300 $question->feedback[$key] = $question->tempgeneralfeedback.'<br/>'.$question->feedback[$key]; 00301 } 00302 } 00303 } 00304 unset($question->tempgeneralfeedback); 00305 } 00306 $maxfraction = -1; 00307 $totalfraction = 0; 00308 foreach($question->fraction as $fraction) { 00309 if ($fraction > 0) { 00310 $totalfraction += $fraction; 00311 } 00312 if ($fraction > $maxfraction) { 00313 $maxfraction = $fraction; 00314 } 00315 } 00316 switch ($question->qtype) { 00317 case SHORTANSWER: 00318 if ($maxfraction != 1) { 00319 $maxfraction = $maxfraction * 100; 00320 $errors[] = "'$question->name': ".get_string("wronggrade", "qformat_webct", $nLineCounter).' '.get_string("fractionsnomax", "question", $maxfraction); 00321 $QuestionOK = FALSE; 00322 } 00323 break; 00324 00325 case MULTICHOICE: 00326 if ($question->single) { 00327 if ($maxfraction != 1) { 00328 $maxfraction = $maxfraction * 100; 00329 $errors[] = "'$question->name': ".get_string("wronggrade", "qformat_webct", $nLineCounter).' '.get_string("fractionsnomax", "question", $maxfraction); 00330 $QuestionOK = FALSE; 00331 } 00332 } else { 00333 $totalfraction = round($totalfraction,2); 00334 if ($totalfraction != 1) { 00335 $totalfraction = $totalfraction * 100; 00336 $errors[] = "'$question->name': ".get_string("wronggrade", "qformat_webct", $nLineCounter).' '.get_string("fractionsaddwrong", "question", $totalfraction); 00337 $QuestionOK = FALSE; 00338 } 00339 } 00340 break; 00341 00342 case CALCULATED: 00343 foreach ($question->answers as $answer) { 00344 if ($formulaerror = qtype_calculated_find_formula_errors($answer)) { 00345 $warnings[] = "'$question->name': ". $formulaerror; 00346 $QuestionOK = FALSE; 00347 } 00348 } 00349 foreach ($question->dataset as $dataset) { 00350 $dataset->itemcount=count($dataset->datasetitem); 00351 } 00352 $question->import_process=TRUE ; 00353 unset($question->answer); //not used in calculated question 00354 break; 00355 case MATCH: 00356 // MDL-10680: 00357 // switch subquestions and subanswers 00358 foreach ($question->subquestions as $id=>$subquestion) { 00359 $temp = $question->subquestions[$id]; 00360 $question->subquestions[$id] = $question->subanswers[$id]; 00361 $question->subanswers[$id] = $temp; 00362 } 00363 if (count($question->answer) < 3){ 00364 // add a dummy missing question 00365 $question->name = 'Dummy question added '.$question->name ; 00366 $question->answer[] = 'dummy'; 00367 $question->subanswers[] = 'dummy'; 00368 $question->subquestions[] = 'dummy'; 00369 $question->fraction[] = '0.0'; 00370 $question->feedback[] = ''; 00371 } 00372 break; 00373 default: 00374 // No problemo 00375 } 00376 } 00377 00378 if ($QuestionOK) { 00379 // echo "<pre>"; print_r ($question); 00380 $questions[] = $question; // store it 00381 unset($question); // and prepare a new one 00382 $question = $this->defaultquestion(); 00383 } 00384 } 00385 $nQuestionStartLine = $nLineCounter; 00386 } 00387 00388 // Processing Question Header 00389 00390 if (preg_match("~^:TYPE:MC:1(.*)~i",$line,$webct_options)) { 00391 // Multiple Choice Question with only one good answer 00392 $question = $this->defaultquestion(); 00393 $question->feedback = array(); 00394 $question->qtype = MULTICHOICE; 00395 $question->single = 1; // Only one answer is allowed 00396 $ignore_rest_of_question = FALSE; 00397 continue; 00398 } 00399 00400 if (preg_match("~^:TYPE:MC:N(.*)~i",$line,$webct_options)) { 00401 // Multiple Choice Question with several good answers 00402 $question = $this->defaultquestion(); 00403 $question->feedback = array(); 00404 $question->qtype = MULTICHOICE; 00405 $question->single = 0; // Many answers allowed 00406 $ignore_rest_of_question = FALSE; 00407 continue; 00408 } 00409 00410 if (preg_match("~^:TYPE:S~i",$line)) { 00411 // Short Answer Question 00412 $question = $this->defaultquestion(); 00413 $question->feedback = array(); 00414 $question->qtype = SHORTANSWER; 00415 $question->usecase = 0; // Ignore case 00416 $ignore_rest_of_question = FALSE; 00417 continue; 00418 } 00419 00420 if (preg_match("~^:TYPE:C~i",$line)) { 00421 // Calculated Question 00422 $question = $this->defaultquestion(); 00423 $question->qtype = CALCULATED; 00424 $question->answers = array(); // No problem as they go as :FORMULA: from webct 00425 $question->units = array(); 00426 $question->dataset = array(); 00427 00428 // To make us pass the end-of-question sanity checks 00429 $question->answer = array('dummy'); 00430 $question->fraction = array('1.0'); 00431 $question->feedback = array(); 00432 00433 $currentchoice = -1; 00434 $ignore_rest_of_question = FALSE; 00435 continue; 00436 } 00437 00438 if (preg_match("~^:TYPE:M~i",$line)) { 00439 // Match Question 00440 $question = $this->defaultquestion(); 00441 $question->qtype = MATCH; 00442 $question->feedback = array(); 00443 $ignore_rest_of_question = FALSE; // match question processing is not debugged 00444 continue; 00445 } 00446 00447 if (preg_match("~^:TYPE:P~i",$line)) { 00448 // Paragraph Question 00449 $warnings[] = get_string("paragraphquestion", "qformat_webct", $nLineCounter); 00450 unset($question); 00451 $ignore_rest_of_question = TRUE; // Question Type not handled by Moodle 00452 continue; 00453 } 00454 00455 if (preg_match("~^:TYPE:~i",$line)) { 00456 // Unknow Question 00457 $warnings[] = get_string("unknowntype", "qformat_webct", $nLineCounter); 00458 unset($question); 00459 $ignore_rest_of_question = TRUE; // Question Type not handled by Moodle 00460 continue; 00461 } 00462 00463 if ($ignore_rest_of_question) { 00464 continue; 00465 } 00466 00467 if (preg_match("~^:TITLE:(.*)~i",$line,$webct_options)) { 00468 $name = trim($webct_options[1]); 00469 if (strlen($name) > 255) { 00470 $name = substr($name,0,250)."..."; 00471 $warnings[] = get_string("questionnametoolong", "qformat_webct", $nLineCounter); 00472 } 00473 $question->name = $name; 00474 continue; 00475 } 00476 00477 if (preg_match("~^:IMAGE:(.*)~i",$line,$webct_options)) { 00478 $filename = trim($webct_options[1]); 00479 if (preg_match("~^http://~i",$filename)) { 00480 $question->image = $filename; 00481 } 00482 continue; 00483 } 00484 00485 // Need to put the parsing of calculated items here to avoid ambitiuosness: 00486 // if question isn't defined yet there is nothing to do here (avoid notices) 00487 if (!isset($question)) { 00488 continue; 00489 } 00490 if (isset($question->qtype ) && CALCULATED == $question->qtype && preg_match( 00491 "~^:([[:lower:]].*|::.*)-(MIN|MAX|DEC|VAL([0-9]+))::?:?($webctnumberregex)~", $line, $webct_options)) { 00492 $datasetname = preg_replace('/^::/', '', $webct_options[1]); 00493 $datasetvalue = qformat_webct_convert_formula($webct_options[4]); 00494 switch ($webct_options[2]) { 00495 case 'MIN': 00496 $question->dataset[$datasetname]->min = $datasetvalue; 00497 break; 00498 case 'MAX': 00499 $question->dataset[$datasetname]->max = $datasetvalue; 00500 break; 00501 case 'DEC': 00502 $datasetvalue = floor($datasetvalue); // int only! 00503 $question->dataset[$datasetname]->length = max(0, $datasetvalue); 00504 break; 00505 default: 00506 // The VAL case: 00507 $question->dataset[$datasetname]->datasetitem[$webct_options[3]] = new stdClass(); 00508 $question->dataset[$datasetname]->datasetitem[$webct_options[3]]->itemnumber = $webct_options[3]; 00509 $question->dataset[$datasetname]->datasetitem[$webct_options[3]]->value = $datasetvalue; 00510 break; 00511 } 00512 continue; 00513 } 00514 00515 00516 $bIsHTMLText = preg_match("~:H$~i",$line); // True if next lines are coded in HTML 00517 if (preg_match("~^:QUESTION~i",$line)) { 00518 $questiontext=""; // Start gathering next lines 00519 continue; 00520 } 00521 00522 if (preg_match("~^:ANSWER([0-9]+):([^:]+):([0-9\.\-]+):(.*)~i",$line,$webct_options)) { 00523 $currentchoice=$webct_options[1]; 00524 $answertext=$webct_options[2]; // Start gathering next lines 00525 $question->fraction[$currentchoice]=($webct_options[3]/100); 00526 continue; 00527 } 00528 00529 if (preg_match("~^:ANSWER([0-9]+):([0-9\.\-]+)~i",$line,$webct_options)) { 00530 $answertext=""; // Start gathering next lines 00531 $currentchoice=$webct_options[1]; 00532 $question->fraction[$currentchoice]=($webct_options[2]/100); 00533 continue; 00534 } 00535 00536 if (preg_match('~^:FORMULA:(.*)~i', $line, $webct_options)) { 00537 // Answer for a CALCULATED question 00538 ++$currentchoice; 00539 $question->answers[$currentchoice] = 00540 qformat_webct_convert_formula($webct_options[1]); 00541 00542 // Default settings: 00543 $question->fraction[$currentchoice] = 1.0; 00544 $question->tolerance[$currentchoice] = 0.0; 00545 $question->tolerancetype[$currentchoice] = 2; // nominal (units in webct) 00546 $question->feedback[$currentchoice] = ''; 00547 $question->correctanswerlength[$currentchoice] = 4; 00548 00549 $datasetnames = question_bank::get_qtype('calculated')-> 00550 find_dataset_names($webct_options[1]); 00551 foreach ($datasetnames as $datasetname) { 00552 $question->dataset[$datasetname] = new stdClass(); 00553 $question->dataset[$datasetname]->datasetitem = array(); 00554 $question->dataset[$datasetname]->name = $datasetname ; 00555 $question->dataset[$datasetname]->distribution = 'uniform'; 00556 $question->dataset[$datasetname]->status ='private'; 00557 } 00558 continue; 00559 } 00560 00561 if (preg_match("~^:L([0-9]+)~i",$line,$webct_options)) { 00562 $answertext=""; // Start gathering next lines 00563 $currentchoice=$webct_options[1]; 00564 $question->fraction[$currentchoice]=1; 00565 continue; 00566 } 00567 00568 if (preg_match("~^:R([0-9]+)~i",$line,$webct_options)) { 00569 $responsetext=""; // Start gathering next lines 00570 $currentchoice=$webct_options[1]; 00571 continue; 00572 } 00573 00574 if (preg_match("~^:REASON([0-9]+):?~i",$line,$webct_options)) { 00575 $feedbacktext=""; // Start gathering next lines 00576 $currentchoice=$webct_options[1]; 00577 continue; 00578 } 00579 if (preg_match("~^:FEEDBACK([0-9]+):?~i",$line,$webct_options)) { 00580 $generalfeedbacktext=""; // Start gathering next lines 00581 $currentchoice=$webct_options[1]; 00582 continue; 00583 } 00584 if (preg_match('~^:FEEDBACK:(.*)~i',$line,$webct_options)) { 00585 $generalfeedbacktext=""; // Start gathering next lines 00586 continue; 00587 } 00588 if (preg_match('~^:LAYOUT:(.*)~i',$line,$webct_options)) { 00589 // ignore since layout in question_multichoice is no more used in moodle 00590 // $webct_options[1] contains either vertical or horizontal ; 00591 continue; 00592 } 00593 00594 if (isset($question->qtype ) && CALCULATED == $question->qtype && preg_match('~^:ANS-DEC:([1-9][0-9]*)~i', $line, $webct_options)) { 00595 // We can but hope that this always appear before the ANSTYPE property 00596 $question->correctanswerlength[$currentchoice] = $webct_options[1]; 00597 continue; 00598 } 00599 00600 if (isset($question->qtype )&& CALCULATED == $question->qtype && preg_match("~^:TOL:($webctnumberregex)~i", $line, $webct_options)) { 00601 // We can but hope that this always appear before the TOL property 00602 $question->tolerance[$currentchoice] = 00603 qformat_webct_convert_formula($webct_options[1]); 00604 continue; 00605 } 00606 00607 if (isset($question->qtype )&& CALCULATED == $question->qtype && preg_match('~^:TOLTYPE:percent~i', $line)) { 00608 // Percentage case is handled as relative in Moodle: 00609 $question->tolerance[$currentchoice] /= 100; 00610 $question->tolerancetype[$currentchoice] = 1; // Relative 00611 continue; 00612 } 00613 00614 if (preg_match('~^:UNITS:(.+)~i', $line, $webct_options) 00615 and $webctunits = trim($webct_options[1])) { 00616 // This is a guess - I really do not know how different webct units are separated... 00617 $webctunits = explode(':', $webctunits); 00618 $unitrec->multiplier = 1.0; // Webct does not seem to support this 00619 foreach ($webctunits as $webctunit) { 00620 $unitrec->unit = trim($webctunit); 00621 $question->units[] = $unitrec; 00622 } 00623 continue; 00624 } 00625 00626 if (!empty($question->units) && preg_match('~^:UNITREQ:(.*)~i', $line, $webct_options) 00627 && !$webct_options[1]) { 00628 // There are units but units are not required so add the no unit alternative 00629 // We can but hope that the UNITS property always appear before this property 00630 $unitrec->unit = ''; 00631 $unitrec->multiplier = 1.0; 00632 $question->units[] = $unitrec; 00633 continue; 00634 } 00635 00636 if (!empty($question->units) && preg_match('~^:UNITCASE:~i', $line)) { 00637 // This could be important but I was not able to figure out how 00638 // it works so I ignore it for now 00639 continue; 00640 } 00641 00642 if (isset($question->qtype )&& CALCULATED == $question->qtype && preg_match('~^:ANSTYPE:dec~i', $line)) { 00643 $question->correctanswerformat[$currentchoice]='1'; 00644 continue; 00645 } 00646 if (isset($question->qtype )&& CALCULATED == $question->qtype && preg_match('~^:ANSTYPE:sig~i', $line)) { 00647 $question->correctanswerformat[$currentchoice]='2'; 00648 continue; 00649 } 00650 } 00651 00652 if (sizeof($errors) > 0) { 00653 echo "<p>".get_string("errorsdetected", "qformat_webct", sizeof($errors))."</p><ul>"; 00654 foreach($errors as $error) { 00655 echo "<li>$error</li>"; 00656 } 00657 echo "</ul>"; 00658 unset($questions); // no questions imported 00659 } 00660 00661 if (sizeof($warnings) > 0) { 00662 echo "<p>".get_string("warningsdetected", "qformat_webct", sizeof($warnings))."</p><ul>"; 00663 foreach($warnings as $warning) { 00664 echo "<li>$warning</li>"; 00665 } 00666 echo "</ul>"; 00667 } 00668 return $questions; 00669 } 00670 } 00671 00672 ?>