Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/mod/lesson/pagetypes/multichoice.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 
00027 defined('MOODLE_INTERNAL') || die();
00028 
00030 define("LESSON_PAGE_MULTICHOICE",   "3");
00031 
00032 class lesson_page_type_multichoice extends lesson_page {
00033 
00034     protected $type = lesson_page::TYPE_QUESTION;
00035     protected $typeidstring = 'multichoice';
00036     protected $typeid = LESSON_PAGE_MULTICHOICE;
00037     protected $string = null;
00038 
00039     public function get_typeid() {
00040         return $this->typeid;
00041     }
00042     public function get_typestring() {
00043         if ($this->string===null) {
00044             $this->string = get_string($this->typeidstring, 'lesson');
00045         }
00046         return $this->string;
00047     }
00048     public function get_idstring() {
00049         return $this->typeidstring;
00050     }
00051 
00057     public function get_jumps() {
00058         global $DB;
00059         $jumps = array();
00060         if ($answers = $this->get_answers()) {
00061             foreach ($answers as $answer) {
00062                 if ($answer->answer === '') {
00063                     // show only jumps for real branches (==have description)
00064                     continue;
00065                 }
00066                 $jumps[] = $this->get_jump_name($answer->jumpto);
00067             }
00068         } else {
00069             // We get here is the lesson was created on a Moodle 1.9 site and
00070             // the lesson contains question pages without any answers.
00071             $jumps[] = $this->get_jump_name($this->properties->nextpageid);
00072         }
00073         return $jumps;
00074     }
00075 
00076     public function get_used_answers() {
00077         $answers = $this->get_answers();
00078         foreach ($answers as $key=>$answer) {
00079             if ($answer->answer === '') {
00080                 unset($answers[$key]);
00081             }
00082         }
00083         return $answers;
00084     }
00085 
00086     public function display($renderer, $attempt) {
00087         global $CFG, $PAGE;
00088         $answers = $this->get_used_answers();
00089         shuffle($answers);
00090         $action = $CFG->wwwroot.'/mod/lesson/continue.php';
00091         $params = array('answers'=>$answers, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents(), 'attempt'=>$attempt);
00092         if ($this->properties->qoption) {
00093             $mform = new lesson_display_answer_form_multichoice_multianswer($action, $params);
00094         } else {
00095             $mform = new lesson_display_answer_form_multichoice_singleanswer($action, $params);
00096         }
00097         $data = new stdClass;
00098         $data->id = $PAGE->cm->id;
00099         $data->pageid = $this->properties->id;
00100         $mform->set_data($data);
00101         return $mform->display();
00102     }
00103 
00104     public function check_answer() {
00105         global $DB, $CFG, $PAGE;
00106         $result = parent::check_answer();
00107 
00108         $formattextdefoptions = new stdClass();
00109         $formattextdefoptions->noclean = true;
00110         $formattextdefoptions->para = false;
00111 
00112         $answers = $this->get_used_answers();
00113         shuffle($answers);
00114         $action = $CFG->wwwroot.'/mod/lesson/continue.php';
00115         $params = array('answers'=>$answers, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
00116         if ($this->properties->qoption) {
00117             $mform = new lesson_display_answer_form_multichoice_multianswer($action, $params);
00118         } else {
00119             $mform = new lesson_display_answer_form_multichoice_singleanswer($action, $params);
00120         }
00121         $data = $mform->get_data();
00122         require_sesskey();
00123 
00124         if (!$data) {
00125             redirect(new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$this->properties->id)));
00126         }
00127 
00128         if ($this->properties->qoption) {
00129             // MULTIANSWER allowed, user's answer is an array
00130 
00131             if (empty($data->answer) || !is_array($data->answer)) {
00132                 $result->noanswer = true;
00133                 return $result;
00134             }
00135 
00136             $studentanswers = array();
00137             foreach ($data->answer as $key=>$value) {
00138                 $studentanswers[] = (int)$key;
00139             }
00140 
00141             // get what the user answered
00142             $result->userresponse = implode(",", $studentanswers);
00143 
00144             // get the answers in a set order, the id order
00145             $answers = $this->get_used_answers();
00146             $ncorrect = 0;
00147             $nhits = 0;
00148             $correctresponse = '';
00149             $wrongresponse = '';
00150             $correctanswerid = 0;
00151             $wronganswerid = 0;
00152             // store student's answers for displaying on feedback page
00153             $result->studentanswer = '';
00154             foreach ($answers as $answer) {
00155                 foreach ($studentanswers as $answerid) {
00156                     if ($answerid == $answer->id) {
00157                         $result->studentanswer .= '<br />'.format_text($answer->answer, $answer->answerformat, $formattextdefoptions);
00158                     }
00159                 }
00160             }
00161             $correctpageid = null;
00162             $wrongpageid = null;
00163             // this is for custom scores.  If score on answer is positive, it is correct
00164             if ($this->lesson->custom) {
00165                 $ncorrect = 0;
00166                 $nhits = 0;
00167                 foreach ($answers as $answer) {
00168                     if ($answer->score > 0) {
00169                         $ncorrect++;
00170 
00171                         foreach ($studentanswers as $answerid) {
00172                             if ($answerid == $answer->id) {
00173                                $nhits++;
00174                             }
00175                         }
00176                         // save the first jumpto page id, may be needed!...
00177                         if (!isset($correctpageid)) {
00178                             // leave in its "raw" state - will converted into a proper page id later
00179                             $correctpageid = $answer->jumpto;
00180                         }
00181                         // save the answer id for scoring
00182                         if ($correctanswerid == 0) {
00183                             $correctanswerid = $answer->id;
00184                         }
00185                         // ...also save any response from the correct answers...
00186                         if (trim(strip_tags($answer->response))) {
00187                             $correctresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
00188                         }
00189                     } else {
00190                         // save the first jumpto page id, may be needed!...
00191                         if (!isset($wrongpageid)) {
00192                             // leave in its "raw" state - will converted into a proper page id later
00193                             $wrongpageid = $answer->jumpto;
00194                         }
00195                         // save the answer id for scoring
00196                         if ($wronganswerid == 0) {
00197                             $wronganswerid = $answer->id;
00198                         }
00199                         // ...and from the incorrect ones, don't know which to use at this stage
00200                         if (trim(strip_tags($answer->response))) {
00201                             $wrongresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
00202                         }
00203                     }
00204                 }
00205             } else {
00206                 foreach ($answers as $answer) {
00207                     if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
00208                         $ncorrect++;
00209                         foreach ($studentanswers as $answerid) {
00210                             if ($answerid == $answer->id) {
00211                                 $nhits++;
00212                             }
00213                         }
00214                         // save the first jumpto page id, may be needed!...
00215                         if (!isset($correctpageid)) {
00216                             // leave in its "raw" state - will converted into a proper page id later
00217                             $correctpageid = $answer->jumpto;
00218                         }
00219                         // save the answer id for scoring
00220                         if ($correctanswerid == 0) {
00221                             $correctanswerid = $answer->id;
00222                         }
00223                         // ...also save any response from the correct answers...
00224                         if (trim(strip_tags($answer->response))) {
00225                             $correctresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
00226                         }
00227                     } else {
00228                         // save the first jumpto page id, may be needed!...
00229                         if (!isset($wrongpageid)) {
00230                             // leave in its "raw" state - will converted into a proper page id later
00231                             $wrongpageid = $answer->jumpto;
00232                         }
00233                         // save the answer id for scoring
00234                         if ($wronganswerid == 0) {
00235                             $wronganswerid = $answer->id;
00236                         }
00237                         // ...and from the incorrect ones, don't know which to use at this stage
00238                         if (trim(strip_tags($answer->response))) {
00239                             $wrongresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
00240                         }
00241                     }
00242                 }
00243             }
00244             if ((count($studentanswers) == $ncorrect) and ($nhits == $ncorrect)) {
00245                 $result->correctanswer = true;
00246                 $result->response  = $correctresponse;
00247                 $result->newpageid = $correctpageid;
00248                 $result->answerid  = $correctanswerid;
00249             } else {
00250                 $result->response  = $wrongresponse;
00251                 $result->newpageid = $wrongpageid;
00252                 $result->answerid  = $wronganswerid;
00253             }
00254         } else {
00255             // only one answer allowed
00256             if (empty($data->answerid) && !is_int($data->answerid)) {
00257                 $result->noanswer = true;
00258                 return $result;
00259             }
00260             $result->answerid = $data->answerid;
00261             if (!$answer = $DB->get_record("lesson_answers", array("id" => $result->answerid))) {
00262                 print_error("Continue: answer record not found");
00263             }
00264             if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
00265                 $result->correctanswer = true;
00266             }
00267             if ($this->lesson->custom) {
00268                 if ($answer->score > 0) {
00269                     $result->correctanswer = true;
00270                 } else {
00271                     $result->correctanswer = false;
00272                 }
00273             }
00274             $result->newpageid = $answer->jumpto;
00275             $result->response  = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
00276             $result->userresponse = format_text($answer->answer, $answer->answerformat, $formattextdefoptions);
00277             $result->studentanswer = $result->userresponse;
00278         }
00279         return $result;
00280     }
00281 
00282     public function option_description_string() {
00283         if ($this->properties->qoption) {
00284             return " - ".get_string("multianswer", "lesson");
00285         }
00286         return parent::option_description_string();
00287     }
00288 
00289     public function display_answers(html_table $table) {
00290         $answers = $this->get_used_answers();
00291         $options = new stdClass;
00292         $options->noclean = true;
00293         $options->para = false;
00294         $i = 1;
00295         foreach ($answers as $answer) {
00296             $cells = array();
00297             if ($this->lesson->custom && $answer->score > 0) {
00298                 // if the score is > 0, then it is correct
00299                 $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
00300             } else if ($this->lesson->custom) {
00301                 $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
00302             } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
00303                 // underline correct answers
00304                 $cells[] = '<span class="correct">'.get_string("answer", "lesson")." $i</span>: \n";
00305             } else {
00306                 $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
00307             }
00308             $cells[] = format_text($answer->answer, $answer->answerformat, $options);
00309             $table->data[] = new html_table_row($cells);
00310 
00311             $cells = array();
00312             $cells[] = "<span class=\"label\">".get_string("response", "lesson")." $i</span>";
00313             $cells[] = format_text($answer->response, $answer->responseformat, $options);
00314             $table->data[] = new html_table_row($cells);
00315 
00316             $cells = array();
00317             $cells[] = "<span class=\"label\">".get_string("score", "lesson").'</span>';
00318             $cells[] = $answer->score;
00319             $table->data[] = new html_table_row($cells);
00320 
00321             $cells = array();
00322             $cells[] = "<span class=\"label\">".get_string("jump", "lesson").'</span>';
00323             $cells[] = $this->get_jump_name($answer->jumpto);
00324             $table->data[] = new html_table_row($cells);
00325             if ($i === 1){
00326                 $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
00327             }
00328             $i++;
00329         }
00330         return $table;
00331     }
00332     public function stats(array &$pagestats, $tries) {
00333         if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
00334             $temp = $tries[$this->lesson->maxattempts - 1];
00335         } else {
00336             // else, user attempted the question less than the max, so grab the last one
00337             $temp = end($tries);
00338         }
00339         if ($this->properties->qoption) {
00340             $userresponse = explode(",", $temp->useranswer);
00341             foreach ($userresponse as $response) {
00342                 if (isset($pagestats[$temp->pageid][$response])) {
00343                     $pagestats[$temp->pageid][$response]++;
00344                 } else {
00345                     $pagestats[$temp->pageid][$response] = 1;
00346                 }
00347             }
00348         } else {
00349             if (isset($pagestats[$temp->pageid][$temp->answerid])) {
00350                 $pagestats[$temp->pageid][$temp->answerid]++;
00351             } else {
00352                 $pagestats[$temp->pageid][$temp->answerid] = 1;
00353             }
00354         }
00355         if (isset($pagestats[$temp->pageid]["total"])) {
00356             $pagestats[$temp->pageid]["total"]++;
00357         } else {
00358             $pagestats[$temp->pageid]["total"] = 1;
00359         }
00360         return true;
00361     }
00362 
00363     public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
00364         $answers = $this->get_used_answers();
00365         $formattextdefoptions = new stdClass;
00366         $formattextdefoptions->para = false;  //I'll use it widely in this page
00367 
00368         foreach ($answers as $answer) {
00369             if ($this->properties->qoption) {
00370                 if ($useranswer == NULL) {
00371                     $userresponse = array();
00372                 } else {
00373                     $userresponse = explode(",", $useranswer->useranswer);
00374                 }
00375                 if (in_array($answer->id, $userresponse)) {
00376                     // make checked
00377                     $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
00378                     if (!isset($answerdata->response)) {
00379                         if ($answer->response == NULL) {
00380                             if ($useranswer->correct) {
00381                                 $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
00382                             } else {
00383                                 $answerdata->response = get_string("thatsthewronganswer", "lesson");
00384                             }
00385                         } else {
00386                             $answerdata->response = $answer->response;
00387                         }
00388                     }
00389                     if (!isset($answerdata->score)) {
00390                         if ($this->lesson->custom) {
00391                             $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
00392                         } elseif ($useranswer->correct) {
00393                             $answerdata->score = get_string("receivedcredit", "lesson");
00394                         } else {
00395                             $answerdata->score = get_string("didnotreceivecredit", "lesson");
00396                         }
00397                     }
00398                 } else {
00399                     // unchecked
00400                     $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
00401                 }
00402                 if (($answer->score > 0 && $this->lesson->custom) || ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) && !$this->lesson->custom)) {
00403                     $data = "<div class=highlight>".$data.' '.format_text($answer->answer,$answer->answerformat,$formattextdefoptions)."</div>";
00404                 } else {
00405                     $data .= format_text($answer->answer,$answer->answerformat,$formattextdefoptions);
00406                 }
00407             } else {
00408                 if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
00409                     // make checked
00410                     $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
00411                     if ($answer->response == NULL) {
00412                         if ($useranswer->correct) {
00413                             $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
00414                         } else {
00415                             $answerdata->response = get_string("thatsthewronganswer", "lesson");
00416                         }
00417                     } else {
00418                         $answerdata->response = $answer->response;
00419                     }
00420                     if ($this->lesson->custom) {
00421                         $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
00422                     } elseif ($useranswer->correct) {
00423                         $answerdata->score = get_string("receivedcredit", "lesson");
00424                     } else {
00425                         $answerdata->score = get_string("didnotreceivecredit", "lesson");
00426                     }
00427                 } else {
00428                     // unchecked
00429                     $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
00430                 }
00431                 if (($answer->score > 0 && $this->lesson->custom) || ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) && !$this->lesson->custom)) {
00432                     $data = "<div class=\"highlight\">".$data.' '.format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</div>";
00433                 } else {
00434                     $data .= format_text($answer->answer,$answer->answerformat,$formattextdefoptions);
00435                 }
00436             }
00437             if (isset($pagestats[$this->properties->id][$answer->id])) {
00438                 $percent = $pagestats[$this->properties->id][$answer->id] / $pagestats[$this->properties->id]["total"] * 100;
00439                 $percent = round($percent, 2);
00440                 $percent .= "% ".get_string("checkedthisone", "lesson");
00441             } else {
00442                 $percent = get_string("noonecheckedthis", "lesson");
00443             }
00444 
00445             $answerdata->answers[] = array($data, $percent);
00446             $answerpage->answerdata = $answerdata;
00447         }
00448         return $answerpage;
00449     }
00450 }
00451 
00452 
00453 class lesson_add_page_form_multichoice extends lesson_add_page_form_base {
00454 
00455     public $qtype = 'multichoice';
00456     public $qtypestring = 'multichoice';
00457 
00458     public function custom_definition() {
00459 
00460         $this->_form->addElement('checkbox', 'qoption', get_string('options', 'lesson'), get_string('multianswer', 'lesson'));
00461         $this->_form->setDefault('qoption', 0);
00462         $this->_form->addHelpButton('qoption', 'multianswer', 'lesson');
00463 
00464         for ($i = 0; $i < $this->_customdata['lesson']->maxanswers; $i++) {
00465             $this->_form->addElement('header', 'answertitle'.$i, get_string('answer').' '.($i+1));
00466             $this->add_answer($i, NULL, ($i<2));
00467             $this->add_response($i);
00468             $this->add_jumpto($i, NULL, ($i == 0 ? LESSON_NEXTPAGE : LESSON_THISPAGE));
00469             $this->add_score($i, null, ($i===0)?1:0);
00470         }
00471     }
00472 }
00473 
00474 class lesson_display_answer_form_multichoice_singleanswer extends moodleform {
00475 
00476     public function definition() {
00477         global $USER, $OUTPUT;
00478         $mform = $this->_form;
00479         $answers = $this->_customdata['answers'];
00480         $lessonid = $this->_customdata['lessonid'];
00481         $contents = $this->_customdata['contents'];
00482         if (array_key_exists('attempt', $this->_customdata)) {
00483             $attempt = $this->_customdata['attempt'];
00484         } else {
00485             $attempt = new stdClass();
00486             $attempt->answerid = null;
00487         }
00488 
00489         $mform->addElement('header', 'pageheader');
00490 
00491         $mform->addElement('html', $OUTPUT->container($contents, 'contents'));
00492 
00493         $hasattempt = false;
00494         $disabled = '';
00495         if (isset($USER->modattempts[$lessonid]) && !empty($USER->modattempts[$lessonid])) {
00496             $hasattempt = true;
00497             $disabled = array('disabled' => 'disabled');
00498         }
00499 
00500         $options = new stdClass;
00501         $options->para = false;
00502         $options->noclean = true;
00503 
00504         $mform->addElement('hidden', 'id');
00505         $mform->setType('id', PARAM_INT);
00506 
00507         $mform->addElement('hidden', 'pageid');
00508         $mform->setType('pageid', PARAM_INT);
00509 
00510         $i = 0;
00511         foreach ($answers as $answer) {
00512             $mform->addElement('html', '<div class="answeroption">');
00513             $mform->addElement('radio','answerid',null,format_text($answer->answer, $answer->answerformat, $options),$answer->id, $disabled);
00514             $mform->setType('answer'.$i, PARAM_INT);
00515             if ($hasattempt && $answer->id == $USER->modattempts[$lessonid]->answerid) {
00516                 $mform->setDefault('answerid', $USER->modattempts[$lessonid]->answerid);
00517             }
00518             $mform->addElement('html', '</div>');
00519             $i++;
00520         }
00521 
00522         if ($hasattempt) {
00523             $this->add_action_buttons(null, get_string("nextpage", "lesson"));
00524         } else {
00525             $this->add_action_buttons(null, get_string("submit", "lesson"));
00526         }
00527     }
00528 
00529 }
00530 
00531 class lesson_display_answer_form_multichoice_multianswer extends moodleform {
00532 
00533     public function definition() {
00534         global $USER, $OUTPUT;
00535         $mform = $this->_form;
00536         $answers = $this->_customdata['answers'];
00537 
00538         $lessonid = $this->_customdata['lessonid'];
00539         $contents = $this->_customdata['contents'];
00540 
00541         $mform->addElement('header', 'pageheader');
00542 
00543         $mform->addElement('html', $OUTPUT->container($contents, 'contents'));
00544 
00545         $hasattempt = false;
00546         $disabled = '';
00547         $useranswers = array();
00548         if (isset($USER->modattempts[$lessonid]) && !empty($USER->modattempts[$lessonid])) {
00549             $hasattempt = true;
00550             $disabled = array('disabled' => 'disabled');
00551             $useranswers = explode(',', $USER->modattempts[$lessonid]->useranswer);
00552         }
00553 
00554         $options = new stdClass;
00555         $options->para = false;
00556         $options->noclean = true;
00557 
00558         $mform->addElement('hidden', 'id');
00559         $mform->setType('id', PARAM_INT);
00560 
00561         $mform->addElement('hidden', 'pageid');
00562         $mform->setType('pageid', PARAM_INT);
00563 
00564         foreach ($answers as $answer) {
00565             $mform->addElement('html', '<div class="answeroption">');
00566             $answerid = 'answer['.$answer->id.']';
00567             if ($hasattempt && in_array($answer->id, $useranswers)) {
00568                 $answerid = 'answer_'.$answer->id;
00569                 $mform->addElement('hidden', 'answer['.$answer->id.']', $answer->answer);
00570                 $mform->setType('answer['.$answer->id.']', PARAM_TEXT);
00571                 $mform->setDefault($answerid, true);
00572                 $mform->setDefault('answer['.$answer->id.']', true);
00573             }
00574             // NOTE: our silly checkbox supports only value '1' - we can not use it like the radiobox above!!!!!!
00575             $mform->addElement('checkbox', $answerid, null, format_text($answer->answer, $answer->answerformat, $options), $disabled);
00576             $mform->setType($answerid, PARAM_INT);
00577 
00578             $mform->addElement('html', '</div>');
00579         }
00580 
00581         if ($hasattempt) {
00582             $this->add_action_buttons(null, get_string("nextpage", "lesson"));
00583         } else {
00584             $this->add_action_buttons(null, get_string("submit", "lesson"));
00585         }
00586     }
00587 
00588 }
 All Data Structures Namespaces Files Functions Variables Enumerations