Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/question/format/webct/format.php
Go to the documentation of this file.
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 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations