Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/mod/lesson/pagetypes/matching.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_MATCHING",      "5");
00031 
00032 class lesson_page_type_matching extends lesson_page {
00033 
00034     protected $type = lesson_page::TYPE_QUESTION;
00035     protected $typeid = LESSON_PAGE_MATCHING;
00036     protected $typeidstring = 'matching';
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     public function display($renderer, $attempt) {
00052         global $USER, $CFG, $PAGE;
00053         $mform = $this->make_answer_form($attempt);
00054         $data = new stdClass;
00055         $data->id = $PAGE->cm->id;
00056         $data->pageid = $this->properties->id;
00057         $mform->set_data($data);
00058         return $mform->display();
00059     }
00060 
00061     protected function make_answer_form($attempt=null) {
00062         global $USER, $CFG;
00063         // don't shuffle answers (could be an option??)
00064         $getanswers = array_slice($this->get_answers(), 2);
00065 
00066         $answers = array();
00067         foreach ($getanswers as $getanswer) {
00068             $answers[$getanswer->id] = $getanswer;
00069         }
00070 
00071         $responses = array();
00072         foreach ($answers as $answer) {
00073             // get all the response
00074             if ($answer->response != NULL) {
00075                 $responses[] = trim($answer->response);
00076             }
00077         }
00078 
00079         $responseoptions = array(''=>get_string('choosedots'));
00080         if (!empty($responses)) {
00081             shuffle($responses);
00082             $responses = array_unique($responses);
00083             foreach ($responses as $response) {
00084                 $responseoptions[htmlspecialchars(trim($response))] = $response;
00085             }
00086         }
00087         if (isset($USER->modattempts[$this->lesson->id]) && !empty($attempt->useranswer)) {
00088             $useranswers = explode(',', $attempt->useranswer);
00089             $t = 0;
00090         } else {
00091             $useranswers = array();
00092         }
00093 
00094         $action = $CFG->wwwroot.'/mod/lesson/continue.php';
00095         $params = array('answers'=>$answers, 'useranswers'=>$useranswers, 'responseoptions'=>$responseoptions, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
00096         $mform = new lesson_display_answer_form_matching($action, $params);
00097         return $mform;
00098     }
00099 
00100     public function create_answers($properties) {
00101         global $DB;
00102         // now add the answers
00103         $newanswer = new stdClass;
00104         $newanswer->lessonid = $this->lesson->id;
00105         $newanswer->pageid = $this->properties->id;
00106         $newanswer->timecreated = $this->properties->timecreated;
00107 
00108         $answers = array();
00109 
00110         // need to add two to offset correct response and wrong response
00111         $this->lesson->maxanswers = $this->lesson->maxanswers + 2;
00112         for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
00113             $answer = clone($newanswer);
00114             if (!empty($properties->answer_editor[$i]) && is_array($properties->answer_editor[$i])) {
00115                 $answer->answer = $properties->answer_editor[$i]['text'];
00116                 $answer->answerformat = $properties->answer_editor[$i]['format'];
00117             }
00118             if (!empty($properties->response_editor[$i]) && is_array($properties->response_editor[$i])) {
00119                 $answer->response = $properties->response_editor[$i]['text'];
00120                 $answer->responseformat = $properties->response_editor[$i]['format'];
00121             }
00122 
00123             if (isset($properties->jumpto[$i])) {
00124                 $answer->jumpto = $properties->jumpto[$i];
00125             }
00126             if ($this->lesson->custom && isset($properties->score[$i])) {
00127                 $answer->score = $properties->score[$i];
00128             }
00129 
00130             if (isset($answer->answer) && $answer->answer != '') {
00131                 $answer->id = $DB->insert_record("lesson_answers", $answer);
00132                 $answers[$answer->id] = new lesson_page_answer($answer);
00133             } else if ($i < 2) {
00134                 $answer->id = $DB->insert_record("lesson_answers", $answer);
00135                 $answers[$answer->id] = new lesson_page_answer($answer);
00136             } else {
00137                 break;
00138             }
00139         }
00140         $this->answers = $answers;
00141         return $answers;
00142     }
00143 
00144     public function check_answer() {
00145         global $CFG, $PAGE;
00146 
00147         $formattextdefoptions = new stdClass();
00148         $formattextdefoptions->noclean = true;
00149         $formattextdefoptions->para = false;
00150 
00151         $result = parent::check_answer();
00152 
00153         $mform = $this->make_answer_form();
00154 
00155         $data = $mform->get_data();
00156         require_sesskey();
00157 
00158         if (!$data) {
00159             redirect(new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$this->properties->id)));
00160         }
00161 
00162         $response = $data->response;
00163         if (!is_array($response)) {
00164             $result->noanswer = true;
00165             return $result;
00166         }
00167 
00168         $answers = $this->get_answers();
00169 
00170         $correct = array_shift($answers);
00171         $wrong   = array_shift($answers);
00172 
00173         foreach ($answers as $key=>$answer) {
00174             if ($answer->answer === '' or $answer->response === '') {
00175                 // incomplete option!
00176                 unset($answers[$key]);
00177             }
00178         }
00179         // get he users exact responses for record keeping
00180         $hits = 0;
00181         $userresponse = array();
00182         foreach ($response as $key => $value) {
00183             foreach($answers as $answer) {
00184                 if ($value === $answer->response) {
00185                     $userresponse[] = $answer->id;
00186                 }
00187                 if ((int)$answer->id === (int)$key) {
00188                     $result->studentanswer .= '<br />'.format_text($answer->answer, $answer->answerformat, $formattextdefoptions).' = '.$value;
00189                 }
00190                 if ((int)$answer->id === (int)$key and $value === $answer->response) {
00191                     $hits++;
00192                 }
00193             }
00194         }
00195         $result->userresponse = implode(",", $userresponse);
00196 
00197         if ($hits == count($answers)) {
00198             $result->correctanswer = true;
00199             $result->response      = format_text($correct->answer, $correct->answerformat, $formattextdefoptions);
00200             $result->answerid      = $correct->id;
00201             $result->newpageid     = $correct->jumpto;
00202         } else {
00203             $result->correctanswer = false;
00204             $result->response      = format_text($wrong->answer, $wrong->answerformat, $formattextdefoptions);
00205             $result->answerid      = $wrong->id;
00206             $result->newpageid     = $wrong->jumpto;
00207         }
00208 
00209         return $result;
00210     }
00211 
00212     public function option_description_string() {
00213         return get_string("firstanswershould", "lesson");
00214     }
00215 
00216     public function display_answers(html_table $table) {
00217         $answers = $this->get_answers();
00218         $options = new stdClass;
00219         $options->noclean = true;
00220         $options->para = false;
00221         $i = 1;
00222         $n = 0;
00223 
00224         foreach ($answers as $answer) {
00225             if ($n < 2) {
00226                 if ($answer->answer != NULL) {
00227                     $cells = array();
00228                     if ($n == 0) {
00229                         $cells[] = "<span class=\"label\">".get_string("correctresponse", "lesson").'</span>';
00230                     } else {
00231                         $cells[] = "<span class=\"label\">".get_string("wrongresponse", "lesson").'</span>';
00232                     }
00233                     $cells[] = format_text($answer->answer, $answer->answerformat, $options);
00234                     $table->data[] = new html_table_row($cells);
00235                 }
00236 
00237                 if ($n == 0) {
00238                     $cells = array();
00239                     $cells[] = '<span class="label">'.get_string("correctanswerscore", "lesson")."</span>: ";
00240                     $cells[] = $answer->score;
00241                     $table->data[] = new html_table_row($cells);
00242 
00243                     $cells = array();
00244                     $cells[] = '<span class="label">'.get_string("correctanswerjump", "lesson")."</span>: ";
00245                     $cells[] = $this->get_jump_name($answer->jumpto);
00246                     $table->data[] = new html_table_row($cells);
00247                 } elseif ($n == 1) {
00248                     $cells = array();
00249                     $cells[] = '<span class="label">'.get_string("wronganswerscore", "lesson")."</span>: ";
00250                     $cells[] = $answer->score;
00251                     $table->data[] = new html_table_row($cells);
00252 
00253                     $cells = array();
00254                     $cells[] = '<span class="label">'.get_string("wronganswerjump", "lesson")."</span>: ";
00255                     $cells[] = $this->get_jump_name($answer->jumpto);
00256                     $table->data[] = new html_table_row($cells);
00257                 }
00258 
00259                 if ($n === 0){
00260                     $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
00261                 }
00262                 $n++;
00263                 $i--;
00264             } else {
00265                 $cells = array();
00266                 if ($this->lesson->custom && $answer->score > 0) {
00267                     // if the score is > 0, then it is correct
00268                     $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
00269                 } else if ($this->lesson->custom) {
00270                     $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
00271                 } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
00272                     $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
00273                 } else {
00274                     $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
00275                 }
00276                 $cells[] = format_text($answer->answer, $answer->answerformat, $options);
00277                 $table->data[] = new html_table_row($cells);
00278 
00279                 $cells = array();
00280                 $cells[] = '<span class="label">'.get_string("matchesanswer", "lesson")." $i</span>: ";
00281                 $cells[] = format_text($answer->response, $answer->responseformat, $options);
00282                 $table->data[] = new html_table_row($cells);
00283             }
00284             $i++;
00285         }
00286         return $table;
00287     }
00296     public function update($properties) {
00297         global $DB, $PAGE;
00298         $answers  = $this->get_answers();
00299         $properties->id = $this->properties->id;
00300         $properties->lessonid = $this->lesson->id;
00301         $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'mod_lesson', 'page_contents', $properties->id);
00302         $DB->update_record("lesson_pages", $properties);
00303 
00304         // need to add two to offset correct response and wrong response
00305         $this->lesson->maxanswers += 2;
00306         for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
00307             if (!array_key_exists($i, $this->answers)) {
00308                 $this->answers[$i] = new stdClass;
00309                 $this->answers[$i]->lessonid = $this->lesson->id;
00310                 $this->answers[$i]->pageid = $this->id;
00311                 $this->answers[$i]->timecreated = $this->timecreated;
00312             }
00313 
00314             if (!empty($properties->answer_editor[$i]) && is_array($properties->answer_editor[$i])) {
00315                 $this->answers[$i]->answer = $properties->answer_editor[$i]['text'];
00316                 $this->answers[$i]->answerformat = $properties->answer_editor[$i]['format'];
00317             }
00318             if (!empty($properties->response_editor[$i]) && is_array($properties->response_editor[$i])) {
00319                 $this->answers[$i]->response = $properties->response_editor[$i]['text'];
00320                 $this->answers[$i]->responseformat = $properties->response_editor[$i]['format'];
00321             }
00322 
00323             if (isset($properties->jumpto[$i])) {
00324                 $this->answers[$i]->jumpto = $properties->jumpto[$i];
00325             }
00326             if ($this->lesson->custom && isset($properties->score[$i])) {
00327                 $this->answers[$i]->score = $properties->score[$i];
00328             }
00329 
00330             // we don't need to check for isset here because properties called it's own isset method.
00331             if ($this->answers[$i]->answer != '') {
00332                 if (!isset($this->answers[$i]->id)) {
00333                     $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
00334                 } else {
00335                     $DB->update_record("lesson_answers", $this->answers[$i]->properties());
00336                 }
00337             } else if ($i < 2) {
00338                 if (!isset($this->answers[$i]->id)) {
00339                     $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
00340                 } else {
00341                     $DB->update_record("lesson_answers", $this->answers[$i]->properties());
00342                 }
00343 
00344             } else if (isset($this->answers[$i]->id)) {
00345                 $DB->delete_records('lesson_answers', array('id'=>$this->answers[$i]->id));
00346                 unset($this->answers[$i]);
00347             }
00348         }
00349         return true;
00350     }
00351     public function stats(array &$pagestats, $tries) {
00352         if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
00353             $temp = $tries[$this->lesson->maxattempts - 1];
00354         } else {
00355             // else, user attempted the question less than the max, so grab the last one
00356             $temp = end($tries);
00357         }
00358         if ($temp->correct) {
00359             if (isset($pagestats[$temp->pageid]["correct"])) {
00360                 $pagestats[$temp->pageid]["correct"]++;
00361             } else {
00362                 $pagestats[$temp->pageid]["correct"] = 1;
00363             }
00364         }
00365         if (isset($pagestats[$temp->pageid]["total"])) {
00366             $pagestats[$temp->pageid]["total"]++;
00367         } else {
00368             $pagestats[$temp->pageid]["total"] = 1;
00369         }
00370         return true;
00371     }
00372     public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
00373         $answers = array();
00374         foreach ($this->get_answers() as $answer) {
00375             $answers[$answer->id] = $answer;
00376         }
00377         $formattextdefoptions = new stdClass;
00378         $formattextdefoptions->para = false;  //I'll use it widely in this page
00379         foreach ($answers as $answer) {
00380             if ($n == 0 && $useranswer != NULL && $useranswer->correct) {
00381                 if ($answer->response == NULL && $useranswer != NULL) {
00382                     $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
00383                 } else {
00384                     $answerdata->response = $answer->response;
00385                 }
00386                 if ($this->lesson->custom) {
00387                     $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
00388                 } else {
00389                     $answerdata->score = get_string("receivedcredit", "lesson");
00390                 }
00391             } elseif ($n == 1 && $useranswer != NULL && !$useranswer->correct) {
00392                 if ($answer->response == NULL && $useranswer != NULL) {
00393                     $answerdata->response = get_string("thatsthewronganswer", "lesson");
00394                 } else {
00395                     $answerdata->response = $answer->response;
00396                 }
00397                 if ($this->lesson->custom) {
00398                     $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
00399                 } else {
00400                     $answerdata->score = get_string("didnotreceivecredit", "lesson");
00401                 }
00402             } elseif ($n > 1) {
00403                 $data = "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->answer))."</option></select>";
00404                 if ($useranswer != NULL) {
00405                     $userresponse = explode(",", $useranswer->useranswer);
00406                     $data .= "<select disabled=\"disabled\"><option selected=\"selected\">";
00407                     if (array_key_exists($i, $userresponse)) {
00408                         $data .= strip_tags(format_string($answers[$userresponse[$i]]->response));
00409                     }
00410                     $data .= "</option></select>";
00411                 } else {
00412                     $data .= "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->response))."</option></select>";
00413                 }
00414 
00415                 if ($n == 2) {
00416                     if (isset($pagestats[$this->properties->id])) {
00417                         if (!array_key_exists('correct', $pagestats[$this->properties->id])) {
00418                             $pagestats[$this->properties->id]["correct"] = 0;
00419                         }
00420                         $percent = $pagestats[$this->properties->id]["correct"] / $pagestats[$this->properties->id]["total"] * 100;
00421                         $percent = round($percent, 2);
00422                         $percent .= "% ".get_string("answeredcorrectly", "lesson");
00423                     } else {
00424                         $percent = get_string("nooneansweredthisquestion", "lesson");
00425                     }
00426                 } else {
00427                     $percent = '';
00428                 }
00429 
00430                 $answerdata->answers[] = array($data, $percent);
00431                 $i++;
00432             }
00433             $n++;
00434             $answerpage->answerdata = $answerdata;
00435         }
00436         return $answerpage;
00437     }
00438     public function get_jumps() {
00439         global $DB;
00440         // The jumps for matching question type are stored in the 1st and 2nd answer record.
00441         $jumps = array();
00442         if ($answers = $DB->get_records("lesson_answers", array("lessonid" => $this->lesson->id, "pageid" => $this->properties->id), 'id', '*', 0, 2)) {
00443             foreach ($answers as $answer) {
00444                 $jumps[] = $this->get_jump_name($answer->jumpto);
00445             }
00446         } else {
00447             $jumps[] = $this->get_jump_name($this->properties->nextpageid);
00448         }
00449         return $jumps;
00450     }
00451 }
00452 
00453 class lesson_add_page_form_matching extends lesson_add_page_form_base {
00454 
00455     public $qtype = 'matching';
00456     public $qtypestring = 'matching';
00457 
00458     public function custom_definition() {
00459 
00460         $this->_form->addElement('header', 'correctresponse', get_string('correctresponse', 'lesson'));
00461         $this->_form->addElement('editor', 'answer_editor[0]', get_string('correctresponse', 'lesson'), array('rows'=>'4', 'columns'=>'80'), array('noclean'=>true));
00462         $this->add_jumpto(0, get_string('correctanswerjump','lesson'), LESSON_NEXTPAGE);
00463         $this->add_score(0, get_string("correctanswerscore", "lesson"), 1);
00464 
00465         $this->_form->addElement('header', 'wrongresponse', get_string('wrongresponse', 'lesson'));
00466         $this->_form->addElement('editor', 'answer_editor[1]', get_string('wrongresponse', 'lesson'), array('rows'=>'4', 'columns'=>'80'), array('noclean'=>true));
00467         $this->add_jumpto(1, get_string('wronganswerjump','lesson'), LESSON_THISPAGE);
00468         $this->add_score(1, get_string("wronganswerscore", "lesson"), 0);
00469 
00470         for ($i = 2; $i < $this->_customdata['lesson']->maxanswers+2; $i++) {
00471             $this->_form->addElement('header', 'matchingpair'.($i-1), get_string('matchingpair', 'lesson', $i-1));
00472             $this->add_answer($i, NULL, ($i < 4));
00473             $this->add_response($i, get_string('matchesanswer','lesson'), ($i < 4));
00474         }
00475     }
00476 }
00477 
00478 
00479 class lesson_display_answer_form_matching extends moodleform {
00480 
00481     public function definition() {
00482         global $USER, $OUTPUT;
00483         $mform = $this->_form;
00484         $answers = $this->_customdata['answers'];
00485         $useranswers = $this->_customdata['useranswers'];
00486         $responseoptions = $this->_customdata['responseoptions'];
00487         $lessonid = $this->_customdata['lessonid'];
00488         $contents = $this->_customdata['contents'];
00489 
00490         $mform->addElement('header', 'pageheader');
00491 
00492         $mform->addElement('html', $OUTPUT->container($contents, 'contents'));
00493 
00494         $hasattempt = false;
00495         $disabled = '';
00496         if (isset($useranswers) && !empty($useranswers)) {
00497             $hasattempt = true;
00498             $disabled = array('disabled' => 'disabled');
00499         }
00500 
00501         $options = new stdClass;
00502         $options->para = false;
00503         $options->noclean = true;
00504 
00505         $mform->addElement('hidden', 'id');
00506         $mform->setType('id', PARAM_INT);
00507 
00508         $mform->addElement('hidden', 'pageid');
00509         $mform->setType('pageid', PARAM_INT);
00510 
00511         $i = 0;
00512         foreach ($answers as $answer) {
00513             $mform->addElement('html', '<div class="answeroption">');
00514             if ($answer->response != NULL) {
00515                 $responseid = 'response['.$answer->id.']';
00516                 if ($hasattempt) {
00517                     $responseid = 'response_'.$answer->id;
00518                     $mform->addElement('hidden', 'response['.$answer->id.']', htmlspecialchars(trim($answers[$useranswers[$i]]->response)));
00519                     $mform->setType('response['.$answer->id.']', PARAM_TEXT);
00520                 }
00521                 $mform->addElement('select', $responseid, format_text($answer->answer,$answer->answerformat,$options), $responseoptions, $disabled);
00522                 $mform->setType($responseid, PARAM_TEXT);
00523                 if ($hasattempt) {
00524                     $mform->setDefault($responseid, htmlspecialchars(trim($answers[$useranswers[$i]]->response))); //TODO: this is suspicious
00525                 } else {
00526                     $mform->setDefault($responseid, 'answeroption');
00527                 }
00528             }
00529             $mform->addElement('html', '</div>');
00530             $i++;
00531         }
00532         if ($hasattempt) {
00533             $this->add_action_buttons(null, get_string("nextpage", "lesson"));
00534         } else {
00535             $this->add_action_buttons(null, get_string("submit", "lesson"));
00536         }
00537     }
00538 
00539 }
 All Data Structures Namespaces Files Functions Variables Enumerations