|
Moodle
2.2.1
http://www.collinsharper.com
|
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 00029 require_once($CFG->dirroot . '/question/type/questiontypebase.php'); 00030 00031 00042 class qtype_random extends question_type { 00044 protected $excludedqtypes = null; 00045 00047 protected $manualqtypes = null; 00048 00054 private $availablequestionsbycategory = array(); 00055 00056 public function menu_name() { 00057 // Don't include this question type in the 'add new question' menu. 00058 return false; 00059 } 00060 00061 public function is_manual_graded() { 00062 return true; 00063 } 00064 00065 public function is_usable_by_random() { 00066 return false; 00067 } 00068 00069 public function is_question_manual_graded($question, $otherquestionsinuse) { 00070 global $DB; 00071 // We take our best shot at working whether a particular question is manually 00072 // graded follows: We look to see if any of the questions that this random 00073 // question might select if of a manually graded type. If a category contains 00074 // a mixture of manual and non-manual questions, and if all the attempts so 00075 // far selected non-manual ones, this will give the wrong answer, but we 00076 // don't care. Even so, this is an expensive calculation! 00077 $this->init_qtype_lists(); 00078 if (!$this->manualqtypes) { 00079 return false; 00080 } 00081 if ($question->questiontext) { 00082 $categorylist = question_categorylist($question->category); 00083 } else { 00084 $categorylist = array($question->category); 00085 } 00086 list($qcsql, $qcparams) = $DB->get_in_or_equal($categorylist); 00087 // TODO use in_or_equal for $otherquestionsinuse and $this->manualqtypes 00088 return $DB->record_exists_select('question', 00089 "category $qcsql 00090 AND parent = 0 00091 AND hidden = 0 00092 AND id NOT IN ($otherquestionsinuse) 00093 AND qtype IN ($this->manualqtypes)", $qcparams); 00094 } 00095 00100 protected function init_qtype_lists() { 00101 if (!is_null($this->excludedqtypes)) { 00102 return; // Already done. 00103 } 00104 $excludedqtypes = array(); 00105 $manualqtypes = array(); 00106 foreach (question_bank::get_all_qtypes() as $qtype) { 00107 $quotedname = "'" . $qtype->name() . "'"; 00108 if (!$qtype->is_usable_by_random()) { 00109 $excludedqtypes[] = $quotedname; 00110 } else if ($qtype->is_manual_graded()) { 00111 $manualqtypes[] = $quotedname; 00112 } 00113 } 00114 $this->excludedqtypes = implode(',', $excludedqtypes); 00115 $this->manualqtypes = implode(',', $manualqtypes); 00116 } 00117 00118 public function display_question_editing_page($mform, $question, $wizardnow) { 00119 global $OUTPUT; 00120 $heading = $this->get_heading(empty($question->id)); 00121 echo $OUTPUT->heading_with_help($heading, 'pluginname', $this->plugin_name()); 00122 $mform->display(); 00123 } 00124 00125 public function get_question_options($question) { 00126 return true; 00127 } 00128 00136 public function question_name($category, $includesubcategories) { 00137 if ($includesubcategories) { 00138 $string = 'randomqplusname'; 00139 } else { 00140 $string = 'randomqname'; 00141 } 00142 return get_string($string, 'qtype_random', shorten_text($category->name, 100)); 00143 } 00144 00145 protected function set_selected_question_name($question, $randomname) { 00146 $a = new stdClass(); 00147 $a->randomname = $randomname; 00148 $a->questionname = $question->name; 00149 $question->name = get_string('selectedby', 'qtype_random', $a); 00150 } 00151 00152 public function save_question($question, $form) { 00153 $form->name = ''; 00154 $form->questiontextformat = FORMAT_MOODLE; 00155 $form->tags = array(); 00156 00157 // Name is not a required field for random questions, but 00158 // parent::save_question Assumes that it is. 00159 return parent::save_question($question, $form); 00160 } 00161 00162 public function save_question_options($question) { 00163 global $DB; 00164 00165 // No options, as such, but we set the parent field to the question's 00166 // own id. Setting the parent field has the effect of hiding this 00167 // question in various places. 00168 $updateobject = new stdClass(); 00169 $updateobject->id = $question->id; 00170 $updateobject->parent = $question->id; 00171 00172 // We also force the question name to be 'Random (categoryname)'. 00173 $category = $DB->get_record('question_categories', 00174 array('id' => $question->category), '*', MUST_EXIST); 00175 $updateobject->name = $this->question_name($category, !empty($question->questiontext)); 00176 return $DB->update_record('question', $updateobject); 00177 } 00178 00188 public function get_available_questions_from_category($categoryid, $subcategories) { 00189 if (isset($this->availablequestionsbycategory[$categoryid][$subcategories])) { 00190 return $this->availablequestionsbycategory[$categoryid][$subcategories]; 00191 } 00192 00193 $this->init_qtype_lists(); 00194 if ($subcategories) { 00195 $categoryids = question_categorylist($categoryid); 00196 } else { 00197 $categoryids = array($categoryid); 00198 } 00199 00200 $questionids = question_bank::get_finder()->get_questions_from_categories( 00201 $categoryids, 'qtype NOT IN (' . $this->excludedqtypes . ')'); 00202 $this->availablequestionsbycategory[$categoryid][$subcategories] = $questionids; 00203 return $questionids; 00204 } 00205 00206 public function make_question($questiondata) { 00207 return $this->choose_other_question($questiondata, array()); 00208 } 00209 00220 public function choose_other_question($questiondata, $excludedquestions, $allowshuffle = true) { 00221 $available = $this->get_available_questions_from_category($questiondata->category, 00222 !empty($questiondata->questiontext)); 00223 shuffle($available); 00224 00225 foreach ($available as $questionid) { 00226 if (in_array($questionid, $excludedquestions)) { 00227 continue; 00228 } 00229 00230 $question = question_bank::load_question($questionid, $allowshuffle); 00231 $this->set_selected_question_name($question, $questiondata->name); 00232 return $question; 00233 } 00234 return null; 00235 } 00236 00237 public function get_random_guess_score($questiondata) { 00238 return null; 00239 } 00240 }