Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/mod/lesson/format.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00030 defined('MOODLE_INTERNAL') || die();
00031 
00038 if (!defined('SHORTANSWER')) {
00039     define("SHORTANSWER",   "shortanswer");
00040     define("TRUEFALSE",     "truefalse");
00041     define("MULTICHOICE",   "multichoice");
00042     define("RANDOM",        "random");
00043     define("MATCH",         "match");
00044     define("RANDOMSAMATCH", "randomsamatch");
00045     define("DESCRIPTION",   "description");
00046     define("NUMERICAL",     "numerical");
00047     define("MULTIANSWER",   "multianswer");
00048     define("CALCULATED",    "calculated");
00049     define("ESSAY",         "essay");
00050 }
00070 function lesson_save_question_options($question, $lesson) {
00071     global $DB;
00072 
00073     // These lines are required to ensure that all page types have
00074     // been loaded for the following switch
00075     if (!($lesson instanceof lesson)) {
00076         $lesson = new lesson($lesson);
00077     }
00078     $manager = lesson_page_type_manager::get($lesson);
00079 
00080     $timenow = time();
00081     $result = new stdClass();
00082     switch ($question->qtype) {
00083         case LESSON_PAGE_SHORTANSWER:
00084 
00085             $answers = array();
00086             $maxfraction = -1;
00087 
00088             // Insert all the new answers
00089             foreach ($question->answer as $key => $dataanswer) {
00090                 if ($dataanswer != "") {
00091                     $answer = new stdClass;
00092                     $answer->lessonid   = $question->lessonid;
00093                     $answer->pageid   = $question->id;
00094                     if ($question->fraction[$key] >=0.5) {
00095                         $answer->jumpto = LESSON_NEXTPAGE;
00096                     }
00097                     $answer->timecreated   = $timenow;
00098                     $answer->grade = $question->fraction[$key] * 100;
00099                     $answer->answer   = $dataanswer;
00100                     $answer->response = $question->feedback[$key]['text'];
00101                     $answer->responseformat = $question->feedback[$key]['format'];
00102                     $answer->id = $DB->insert_record("lesson_answers", $answer);
00103                     $answers[] = $answer->id;
00104                     if ($question->fraction[$key] > $maxfraction) {
00105                         $maxfraction = $question->fraction[$key];
00106                     }
00107                 }
00108             }
00109 
00110 
00112             if ($maxfraction != 1) {
00113                 $maxfraction = $maxfraction * 100;
00114                 $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
00115                 return $result;
00116             }
00117             break;
00118 
00119         case LESSON_PAGE_NUMERICAL:   // Note similarities to SHORTANSWER
00120 
00121             $answers = array();
00122             $maxfraction = -1;
00123 
00124 
00125             // for each answer store the pair of min and max values even if they are the same
00126             foreach ($question->answer as $key => $dataanswer) {
00127                 if ($dataanswer != "") {
00128                     $answer = new stdClass;
00129                     $answer->lessonid   = $question->lessonid;
00130                     $answer->pageid   = $question->id;
00131                     $answer->jumpto = LESSON_NEXTPAGE;
00132                     $answer->timecreated   = $timenow;
00133                     $answer->grade = $question->fraction[$key] * 100;
00134                     $min = $question->answer[$key] - $question->tolerance[$key];
00135                     $max = $question->answer[$key] + $question->tolerance[$key];
00136                     $answer->answer   = $min.":".$max;
00137                     // $answer->answer   = $question->min[$key].":".$question->max[$key]; original line for min/max
00138                     $answer->response = $question->feedback[$key]['text'];
00139                     $answer->responseformat = $question->feedback[$key]['format'];
00140                     $answer->id = $DB->insert_record("lesson_answers", $answer);
00141 
00142                     $answers[] = $answer->id;
00143                     if ($question->fraction[$key] > $maxfraction) {
00144                         $maxfraction = $question->fraction[$key];
00145                     }
00146                 }
00147             }
00148 
00150             if ($maxfraction != 1) {
00151                 $maxfraction = $maxfraction * 100;
00152                 $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
00153                 return $result;
00154             }
00155         break;
00156 
00157 
00158         case LESSON_PAGE_TRUEFALSE:
00159 
00160             // the truth
00161             $answer = new stdClass();
00162             $answer->lessonid   = $question->lessonid;
00163             $answer->pageid = $question->id;
00164             $answer->timecreated   = $timenow;
00165             $answer->answer = get_string("true", "quiz");
00166             $answer->grade = $question->correctanswer * 100;
00167             if ($answer->grade > 50 ) {
00168                 $answer->jumpto = LESSON_NEXTPAGE;
00169             }
00170             if (isset($question->feedbacktrue)) {
00171                 $answer->response = $question->feedbacktrue['text'];
00172                 $answer->responseformat = $question->feedbacktrue['format'];
00173             }
00174             $DB->insert_record("lesson_answers", $answer);
00175 
00176             // the lie
00177             $answer = new stdClass;
00178             $answer->lessonid   = $question->lessonid;
00179             $answer->pageid = $question->id;
00180             $answer->timecreated   = $timenow;
00181             $answer->answer = get_string("false", "quiz");
00182             $answer->grade = (1 - (int)$question->correctanswer) * 100;
00183             if ($answer->grade > 50 ) {
00184                 $answer->jumpto = LESSON_NEXTPAGE;
00185             }
00186             if (isset($question->feedbackfalse)) {
00187                 $answer->response = $question->feedbackfalse['text'];
00188                 $answer->responseformat = $question->feedbackfalse['format'];
00189             }
00190             $DB->insert_record("lesson_answers", $answer);
00191 
00192           break;
00193 
00194         case LESSON_PAGE_MULTICHOICE:
00195 
00196             $totalfraction = 0;
00197             $maxfraction = -1;
00198 
00199             $answers = array();
00200 
00201             // Insert all the new answers
00202             foreach ($question->answer as $key => $dataanswer) {
00203                 if ($dataanswer != "") {
00204                     $answer = new stdClass;
00205                     $answer->lessonid   = $question->lessonid;
00206                     $answer->pageid   = $question->id;
00207                     $answer->timecreated   = $timenow;
00208                     $answer->grade = $question->fraction[$key] * 100;
00209                     // changed some defaults
00210                     /* Original Code
00211                     if ($answer->grade > 50 ) {
00212                         $answer->jumpto = LESSON_NEXTPAGE;
00213                     }
00214                     Replaced with:                    */
00215                     if ($answer->grade > 50 ) {
00216                         $answer->jumpto = LESSON_NEXTPAGE;
00217                         $answer->score = 1;
00218                     }
00219                     // end Replace
00220                     $answer->answer   = $dataanswer['text'];
00221                     $answer->answerformat   = $dataanswer['format'];
00222                     $answer->response = $question->feedback[$key]['text'];
00223                     $answer->responseformat = $question->feedback[$key]['format'];
00224                     $answer->id = $DB->insert_record("lesson_answers", $answer);
00225                     // for Sanity checks
00226                     if ($question->fraction[$key] > 0) {
00227                         $totalfraction += $question->fraction[$key];
00228                     }
00229                     if ($question->fraction[$key] > $maxfraction) {
00230                         $maxfraction = $question->fraction[$key];
00231                     }
00232                 }
00233             }
00234 
00236             if ($question->single) {
00237                 if ($maxfraction != 1) {
00238                     $maxfraction = $maxfraction * 100;
00239                     $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
00240                     return $result;
00241                 }
00242             } else {
00243                 $totalfraction = round($totalfraction,2);
00244                 if ($totalfraction != 1) {
00245                     $totalfraction = $totalfraction * 100;
00246                     $result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction);
00247                     return $result;
00248                 }
00249             }
00250         break;
00251 
00252         case LESSON_PAGE_MATCHING:
00253 
00254             $subquestions = array();
00255 
00256             $defaultanswer = new stdClass;
00257             $defaultanswer->lessonid   = $question->lessonid;
00258             $defaultanswer->pageid   = $question->id;
00259             $defaultanswer->timecreated   = $timenow;
00260             $defaultanswer->grade = 0;
00261 
00262             // The first answer should always be the correct answer
00263             $correctanswer = clone($defaultanswer);
00264             $correctanswer->answer = get_string('thatsthecorrectanswer', 'lesson');
00265             $DB->insert_record("lesson_answers", $correctanswer);
00266 
00267             // The second answer should always be the wrong answer
00268             $wronganswer = clone($defaultanswer);
00269             $wronganswer->answer = get_string('thatsthewronganswer', 'lesson');
00270             $DB->insert_record("lesson_answers", $wronganswer);
00271 
00272             $i = 0;
00273             // Insert all the new question+answer pairs
00274             foreach ($question->subquestions as $key => $questiontext) {
00275                 $answertext = $question->subanswers[$key];
00276                 if (!empty($questiontext) and !empty($answertext)) {
00277                     $answer = clone($defaultanswer);
00278                     $answer->answer = $questiontext['text'];
00279                     $answer->answerformat   = $questiontext['format'];
00280                     $answer->response   = $answertext;
00281                     if ($i == 0) {
00282                         // first answer contains the correct answer jump
00283                         $answer->jumpto = LESSON_NEXTPAGE;
00284                     }
00285                     $subquestions[] = $DB->insert_record("lesson_answers", $answer);
00286                     $i++;
00287                 }
00288             }
00289 
00290             if (count($subquestions) < 3) {
00291                 $result->notice = get_string("notenoughsubquestions", "quiz");
00292                 return $result;
00293             }
00294             break;
00295         default:
00296             $result->error = "Unsupported question type ($question->qtype)!";
00297             return $result;
00298     }
00299     return true;
00300 }
00301 
00302 
00303 class qformat_default {
00304 
00305     var $displayerrors = true;
00306     var $category = NULL;
00307     var $questionids = array();
00308     var $qtypeconvert = array(NUMERICAL   => LESSON_PAGE_NUMERICAL,
00309                               MULTICHOICE => LESSON_PAGE_MULTICHOICE,
00310                               TRUEFALSE   => LESSON_PAGE_TRUEFALSE,
00311                               SHORTANSWER => LESSON_PAGE_SHORTANSWER,
00312                               MATCH       => LESSON_PAGE_MATCHING
00313                               );
00314 
00315     // Importing functions
00316     function provide_import() {
00317         return false;
00318     }
00319 
00320     function importpreprocess() {
00321         // Does any pre-processing that may be desired
00322         return true;
00323     }
00324 
00325     function importprocess($filename, $lesson, $pageid) {
00326         global $DB, $OUTPUT;
00327 
00329         $timenow = time();
00330 
00331         if (! $lines = $this->readdata($filename)) {
00332             echo $OUTPUT->notification("File could not be read, or was empty");
00333             return false;
00334         }
00335 
00336         if (! $questions = $this->readquestions($lines)) {   // Extract all the questions
00337             echo $OUTPUT->notification("There are no questions in this file!");
00338             return false;
00339         }
00340 
00341         //Avoid category as question type
00342         echo $OUTPUT->notification(get_string('importcount', 'lesson',
00343                 $this->count_questions($questions)), 'notifysuccess');
00344 
00345         $count = 0;
00346 
00347         $unsupportedquestions = 0;
00348 
00349         foreach ($questions as $question) {   // Process and store each question
00350             switch ($question->qtype) {
00351                 //TODO: Bad way to bypass category in data... Quickfix for MDL-27964
00352                 case 'category':
00353                     break;
00354                 // the good ones
00355                 case SHORTANSWER :
00356                 case NUMERICAL :
00357                 case TRUEFALSE :
00358                 case MULTICHOICE :
00359                 case MATCH :
00360                     $count++;
00361 
00362                     //Show nice formated question in one line.
00363                     echo "<hr><p><b>$count</b>. ".$this->format_question_text($question)."</p>";
00364 
00365                     $newpage = new stdClass;
00366                     $newpage->lessonid = $lesson->id;
00367                     $newpage->qtype = $this->qtypeconvert[$question->qtype];
00368                     switch ($question->qtype) {
00369                         case SHORTANSWER :
00370                             if (isset($question->usecase)) {
00371                                 $newpage->qoption = $question->usecase;
00372                             }
00373                             break;
00374                         case MULTICHOICE :
00375                             if (isset($question->single)) {
00376                                 $newpage->qoption = !$question->single;
00377                             }
00378                             break;
00379                     }
00380                     $newpage->timecreated = $timenow;
00381                     if ($question->name != $question->questiontext) {
00382                         $newpage->title = $question->name;
00383                     } else {
00384                         $newpage->title = "Page $count";
00385                     }
00386                     $newpage->contents = $question->questiontext;
00387 
00388                     // set up page links
00389                     if ($pageid) {
00390                         // the new page follows on from this page
00391                         if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
00392                             print_error('invalidpageid', 'lesson');
00393                         }
00394                         $newpage->prevpageid = $pageid;
00395                         $newpage->nextpageid = $page->nextpageid;
00396                         // insert the page and reset $pageid
00397                         $newpageid = $DB->insert_record("lesson_pages", $newpage);
00398                         // update the linked list
00399                         $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
00400 
00401                     } else {
00402                         // new page is the first page
00403                         // get the existing (first) page (if any)
00404                         $params = array ("lessonid" => $lesson->id, "prevpageid" => 0);
00405                         if (!$page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
00406                             // there are no existing pages
00407                             $newpage->prevpageid = 0; // this is a first page
00408                             $newpage->nextpageid = 0; // this is the only page
00409                             $newpageid = $DB->insert_record("lesson_pages", $newpage);
00410                         } else {
00411                             // there are existing pages put this at the start
00412                             $newpage->prevpageid = 0; // this is a first page
00413                             $newpage->nextpageid = $page->id;
00414                             $newpageid = $DB->insert_record("lesson_pages", $newpage);
00415                             // update the linked list
00416                             $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->id));
00417                         }
00418                     }
00419                     // reset $pageid and put the page ID in $question, used in save_question_option()
00420                     $pageid = $newpageid;
00421                     $question->id = $newpageid;
00422 
00423                     $this->questionids[] = $question->id;
00424 
00425                     // Now to save all the answers and type-specific options
00426 
00427                     $question->lessonid = $lesson->id; // needed for foreign key
00428                     $question->qtype = $this->qtypeconvert[$question->qtype];
00429                     $result = lesson_save_question_options($question, $lesson);
00430 
00431                     if (!empty($result->error)) {
00432                         echo $OUTPUT->notification($result->error);
00433                         return false;
00434                     }
00435 
00436                     if (!empty($result->notice)) {
00437                         echo $OUTPUT->notification($result->notice);
00438                         return true;
00439                     }
00440                     break;
00441             // the Bad ones
00442                 default :
00443                     $unsupportedquestions++;
00444                     break;
00445             }
00446 
00447         }
00448         if ($unsupportedquestions) {
00449             echo $OUTPUT->notification(get_string('unknownqtypesnotimported', 'lesson', $unsupportedquestions));
00450         }
00451         return true;
00452     }
00453 
00461     protected function count_questions($questions) {
00462         $count = 0;
00463         if (!is_array($questions)) {
00464             return $count;
00465         }
00466         foreach ($questions as $question) {
00467             if (!is_object($question) || !isset($question->qtype) ||
00468                     ($question->qtype == 'category')) {
00469                 continue;
00470             }
00471             $count++;
00472         }
00473         return $count;
00474     }
00475 
00476     function readdata($filename) {
00478 
00479         if (is_readable($filename)) {
00480             $filearray = file($filename);
00481 
00483             if (preg_match("/\r/", $filearray[0]) AND !preg_match("/\n/", $filearray[0])) {
00484                 return explode("\r", $filearray[0]);
00485             } else {
00486                 return $filearray;
00487             }
00488         }
00489         return false;
00490     }
00491 
00492     protected function readquestions($lines) {
00497 
00498         $questions = array();
00499         $currentquestion = array();
00500 
00501         foreach ($lines as $line) {
00502             $line = trim($line);
00503             if (empty($line)) {
00504                 if (!empty($currentquestion)) {
00505                     if ($question = $this->readquestion($currentquestion)) {
00506                         $questions[] = $question;
00507                     }
00508                     $currentquestion = array();
00509                 }
00510             } else {
00511                 $currentquestion[] = $line;
00512             }
00513         }
00514 
00515         if (!empty($currentquestion)) {  // There may be a final question
00516             if ($question = $this->readquestion($currentquestion)) {
00517                 $questions[] = $question;
00518             }
00519         }
00520 
00521         return $questions;
00522     }
00523 
00524 
00525     function readquestion($lines) {
00529 
00530         echo "<p>This flash question format has not yet been completed!</p>";
00531 
00532         return NULL;
00533     }
00534 
00535     function defaultquestion() {
00536     // returns an "empty" question
00537     // Somewhere to specify question parameters that are not handled
00538     // by import but are required db fields.
00539     // This should not be overridden.
00540         global $CFG;
00541 
00542         $question = new stdClass();
00543         $question->shuffleanswers = get_config('quiz', 'shuffleanswers');
00544         $question->defaultmark = 1;
00545         $question->image = "";
00546         $question->usecase = 0;
00547         $question->multiplier = array();
00548         $question->generalfeedback = '';
00549         $question->correctfeedback = '';
00550         $question->partiallycorrectfeedback = '';
00551         $question->incorrectfeedback = '';
00552         $question->answernumbering = 'abc';
00553         $question->penalty = 0.1;
00554         $question->length = 1;
00555         $question->qoption = 0;
00556         $question->layout = 1;
00557 
00558         // this option in case the questiontypes class wants
00559         // to know where the data came from
00560         $question->export_process = true;
00561         $question->import_process = true;
00562 
00563         return $question;
00564     }
00565 
00566     function importpostprocess() {
00570         return true;
00571     }
00572 
00577     protected function format_question_text($question) {
00578         $formatoptions = new stdClass();
00579         $formatoptions->noclean = true;
00580         return html_to_text(format_text($question->questiontext,
00581                 $question->questiontextformat, $formatoptions), 0, false);
00582     }
00583 }
00584 
00585 
 All Data Structures Namespaces Files Functions Variables Enumerations