1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Question type class for the drag-and-drop onto image question type. 19 * 20 * @package qtype_ddimageortext 21 * @copyright 2009 The Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once($CFG->libdir . '/questionlib.php'); 29 require_once($CFG->dirroot . '/question/engine/lib.php'); 30 require_once($CFG->dirroot . '/question/format/xml/format.php'); 31 require_once($CFG->dirroot . '/question/type/gapselect/questiontypebase.php'); 32 33 /** 34 * The drag-and-drop onto image question type class. 35 * 36 * @copyright 2009 The Open University 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class qtype_ddtoimage_base extends question_type { 40 /** 41 * Returns the choice group key. 42 * 43 * @return string 44 */ 45 protected function choice_group_key() { 46 return 'draggroup'; 47 } 48 49 public function get_question_options($question) { 50 global $DB; 51 $dbprefix = 'qtype_'.$this->name(); 52 $question->options = $DB->get_record($dbprefix, 53 array('questionid' => $question->id), '*', MUST_EXIST); 54 $question->options->drags = $DB->get_records($dbprefix.'_drags', 55 array('questionid' => $question->id), 'no ASC', '*'); 56 $question->options->drops = $DB->get_records($dbprefix.'_drops', 57 array('questionid' => $question->id), 'no ASC', '*'); 58 parent::get_question_options($question); 59 } 60 61 protected function initialise_question_instance(question_definition $question, $questiondata) { 62 parent::initialise_question_instance($question, $questiondata); 63 $question->shufflechoices = $questiondata->options->shuffleanswers; 64 65 $this->initialise_combined_feedback($question, $questiondata, true); 66 67 $question->choices = array(); 68 $choiceindexmap = array(); 69 70 // Store the choices in arrays by group. 71 // This code is weird. The first choice in each group gets key 1 in the 72 // $question->choices[$choice->choice_group()] array, and the others get 73 // key $choice->no. Therefore you need to think carefully whether you 74 // are using the key, or $choice->no. This is presumably a mistake, but 75 // one that is now essentially un-fixable, since many questions of this 76 // type have been attempted, and theys keys get stored in the attempt data. 77 foreach ($questiondata->options->drags as $dragdata) { 78 79 $choice = $this->make_choice($dragdata); 80 81 if (array_key_exists($choice->choice_group(), $question->choices)) { 82 $question->choices[$choice->choice_group()][$dragdata->no] = $choice; 83 } else { 84 $question->choices[$choice->choice_group()][1] = $choice; 85 } 86 87 end($question->choices[$choice->choice_group()]); 88 $choiceindexmap[$dragdata->no] = array($choice->choice_group(), 89 key($question->choices[$choice->choice_group()])); 90 } 91 92 $question->places = array(); 93 $question->rightchoices = array(); 94 95 $i = 1; 96 97 foreach ($questiondata->options->drops as $dropdata) { 98 list($group, $choiceindex) = $choiceindexmap[$dropdata->choice]; 99 $dropdata->group = $group; 100 $question->places[$dropdata->no] = $this->make_place($dropdata); 101 $question->rightchoices[$dropdata->no] = $choiceindex; 102 } 103 } 104 105 /** 106 * Convert files into text output in the given format. 107 * This method is copied from qformat_default as a quick fix, as the method there is 108 * protected. 109 * @param array $files 110 * @param int $indent Number of spaces to indent 111 * @return string $string 112 */ 113 public function write_files($files, $indent) { 114 if (empty($files)) { 115 return ''; 116 } 117 $string = ''; 118 foreach ($files as $file) { 119 if ($file->is_directory()) { 120 continue; 121 } 122 $string .= str_repeat(' ', $indent); 123 $string .= '<file name="' . $file->get_filename() . '" encoding="base64">'; 124 $string .= base64_encode($file->get_content()); 125 $string .= "</file>\n"; 126 } 127 return $string; 128 } 129 130 public function get_possible_responses($questiondata) { 131 $question = $this->make_question($questiondata); 132 133 $parts = array(); 134 foreach ($question->places as $placeno => $place) { 135 $choices = array(); 136 137 foreach ($question->choices[$place->group] as $i => $choice) { 138 $correct = $question->rightchoices[$placeno] == $i; 139 $choices[$choice->no] = new question_possible_response($choice->summarise(), $correct ? 1 : 0); 140 } 141 $choices[null] = question_possible_response::no_response(); 142 143 $parts[$placeno] = $choices; 144 } 145 146 return $parts; 147 } 148 149 public function get_random_guess_score($questiondata) { 150 $question = $this->make_question($questiondata); 151 return $question->get_random_guess_score(); 152 } 153 public function delete_question($questionid, $contextid) { 154 global $DB; 155 $DB->delete_records('qtype_'.$this->name(), array('questionid' => $questionid)); 156 $DB->delete_records('qtype_'.$this->name().'_drags', array('questionid' => $questionid)); 157 $DB->delete_records('qtype_'.$this->name().'_drops', array('questionid' => $questionid)); 158 return parent::delete_question($questionid, $contextid); 159 } 160 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body