7 /// QUESTION TYPE CLASS //////////////////
8 class question_truefalse_qtype
extends default_questiontype
{
14 function save_question_options($question) {
15 $result = new stdClass
;
17 // fetch old answer ids so that we can reuse them
18 if (!$oldanswers = get_records("question_answers", "question", $question->id
, "id ASC")) {
19 $oldanswers = array();
23 if ($true = array_shift($oldanswers)) { // Existing answer, so reuse it
24 $true->answer
= get_string("true", "quiz");
25 $true->fraction
= $question->answer
;
26 $true->feedback
= $question->feedbacktrue
;
27 if (!update_record("question_answers", $true)) {
28 $result->error
= "Could not update quiz answer \"true\")!";
33 $true->answer
= get_string("true", "quiz");
34 $true->question
= $question->id
;
35 $true->fraction
= $question->answer
;
36 $true->feedback
= $question->feedbacktrue
;
37 if (!$true->id
= insert_record("question_answers", $true)) {
38 $result->error
= "Could not insert quiz answer \"true\")!";
43 // Save answer 'False'
44 if ($false = array_shift($oldanswers)) { // Existing answer, so reuse it
45 $false->answer
= get_string("false", "quiz");
46 $false->fraction
= 1 - (int)$question->answer
;
47 $false->feedback
= $question->feedbackfalse
;
48 if (!update_record("question_answers", $false)) {
49 $result->error
= "Could not insert quiz answer \"false\")!";
54 $false->answer
= get_string("false", "quiz");
55 $false->question
= $question->id
;
56 $false->fraction
= 1 - (int)$question->answer
;
57 $false->feedback
= $question->feedbackfalse
;
58 if (!$false->id
= insert_record("question_answers", $false)) {
59 $result->error
= "Could not insert quiz answer \"false\")!";
64 // delete any leftover old answer records (there couldn't really be any, but who knows)
65 if (!empty($oldanswers)) {
66 foreach($oldanswers as $oa) {
67 delete_records('question_answers', 'id', $oa->id
);
71 // Save question options in question_truefalse table
72 if ($options = get_record("question_truefalse", "question", $question->id
)) {
73 // No need to do anything, since the answer IDs won't have changed
74 // But we'll do it anyway, just for robustness
75 $options->trueanswer
= $true->id
;
76 $options->falseanswer
= $false->id
;
77 if (!update_record("question_truefalse", $options)) {
78 $result->error
= "Could not update quiz truefalse options! (id=$options->id)";
83 $options->question
= $question->id
;
84 $options->trueanswer
= $true->id
;
85 $options->falseanswer
= $false->id
;
86 if (!insert_record("question_truefalse", $options)) {
87 $result->error
= "Could not insert quiz truefalse options!";
95 * Loads the question type specific options for the question.
97 function get_question_options(&$question) {
98 // Get additional information from database
99 // and attach it to the question object
100 if (!$question->options
= get_record('question_truefalse', 'question', $question->id
)) {
101 notify('Error: Missing question options!');
105 if (!$question->options
->answers
= get_records('question_answers', 'question', $question->id
)) {
106 notify('Error: Missing question answers!');
114 * Deletes question from the question-type specific tables
116 * @return boolean Success/Failure
117 * @param object $question The question being deleted
119 function delete_question($questionid) {
120 delete_records("question_truefalse", "question", $questionid);
124 function get_correct_responses(&$question, &$state) {
125 // The correct answer is the one which gives full marks
126 foreach ($question->options
->answers
as $answer) {
127 if (((int) $answer->fraction
) === 1) {
128 return array('' => $answer->id
);
135 * Prints the main content of the question including any interactions
137 function print_question_formulation_and_controls(&$question, &$state,
138 $cmoptions, $options) {
141 $readonly = $options->readonly ?
' disabled="disabled"' : '';
143 $formatoptions = new stdClass
;
144 $formatoptions->noclean
= true;
145 $formatoptions->para
= false;
147 // Print question formulation
148 $questiontext = format_text($question->questiontext
,
149 $question->questiontextformat
,
150 $formatoptions, $cmoptions->course
);
151 $image = get_question_image($question, $cmoptions->course
);
153 $answers = &$question->options
->answers
;
154 $trueanswer = &$answers[$question->options
->trueanswer
];
155 $falseanswer = &$answers[$question->options
->falseanswer
];
156 $correctanswer = ($trueanswer->fraction
== 1) ?
$trueanswer : $falseanswer;
158 // Work out which radio button to select (if any)
159 $truechecked = ($state->responses
[''] == $trueanswer->id
) ?
' checked="checked"' : '';
160 $falsechecked = ($state->responses
[''] == $falseanswer->id
) ?
' checked="checked"' : '';
162 // Work out which answer is correct if we need to highlight it
163 if ($options->correct_responses
) {
164 $trueclass = ($trueanswer->fraction
) ?
' class="highlight"' : '';
165 $falseclass = ($falseanswer->fraction
) ?
' class="highlight"' : '';
171 $inputname = ' name="'.$question->name_prefix
.'" ';
172 $trueid = $question->name_prefix
.'true';
173 $falseid = $question->name_prefix
.'false';
175 $radiotrue = '<input type="radio"' . $truechecked . $readonly . $inputname
176 . 'id="'.$trueid . '" value="' . $trueanswer->id
. '" alt="'
177 . s($trueanswer->answer
) . '" /><label for="'.$trueid . '">'
178 . s($trueanswer->answer
) . '</label>';
179 $radiofalse = '<input type="radio"' . $falsechecked . $readonly . $inputname
180 . 'id="'.$falseid . '" value="' . $falseanswer->id
. '" alt="'
181 . s($falseanswer->answer
) . '" /><label for="'.$falseid . '">'
182 . s($falseanswer->answer
) . '</label>';
185 if ($options->feedback
and isset($answers[$state->responses
['']])) {
186 $chosenanswer = $answers[$state->responses
['']];
187 $feedback = format_text($chosenanswer->feedback
, true, $formatoptions, $cmoptions->course
);
190 include("$CFG->dirroot/question/type/truefalse/display.html");
193 function grade_responses(&$question, &$state, $cmoptions) {
194 if (isset($question->options
->answers
[$state->responses
['']])) {
195 $state->raw_grade
= $question->options
->answers
[$state->responses
['']]->fraction
* $question->maxgrade
;
197 $state->raw_grade
= 0;
199 // Only allow one attempt at the question
200 $state->penalty
= 1 * $question->maxgrade
;
202 // mark the state as graded
203 $state->event
= ($state->event
== QUESTION_EVENTCLOSE
) ? QUESTION_EVENTCLOSEANDGRADE
: QUESTION_EVENTGRADE
;
208 function response_summary($question, $state, $length=80) {
209 if (isset($question->options
->answers
[$state->answer
])) {
210 $responses = $question->options
->answers
[$state->answer
]->answer
;
217 function get_actual_response($question, $state) {
218 if (isset($question->options
->answers
[$state->responses
['']])) {
219 $responses[] = $question->options
->answers
[$state->responses
['']]->answer
;
226 /// BACKUP FUNCTIONS ////////////////////////////
229 * Backup the data in a truefalse question
231 * This is used in question/backuplib.php
233 function backup($bf,$preferences,$question,$level=6) {
237 $truefalses = get_records("question_truefalse","question",$question,"id");
238 //If there are truefalses
240 //Iterate over each truefalse
241 foreach ($truefalses as $truefalse) {
242 $status = fwrite ($bf,start_tag("TRUEFALSE",$level,true));
243 //Print truefalse contents
244 fwrite ($bf,full_tag("TRUEANSWER",$level+
1,false,$truefalse->trueanswer
));
245 fwrite ($bf,full_tag("FALSEANSWER",$level+
1,false,$truefalse->falseanswer
));
246 $status = fwrite ($bf,end_tag("TRUEFALSE",$level,true));
248 //Now print question_answers
249 $status = question_backup_answers($bf,$preferences,$question);
254 /// RESTORE FUNCTIONS /////////////////
257 * Restores the data in the question
259 * This is used in question/restorelib.php
261 function restore($old_question_id,$new_question_id,$info,$restore) {
265 //Get the truefalse array
266 $truefalses = $info['#']['TRUEFALSE'];
268 //Iterate over truefalse
269 for($i = 0; $i < sizeof($truefalses); $i++
) {
270 $tru_info = $truefalses[$i];
272 //Now, build the question_truefalse record structure
273 $truefalse = new stdClass
;
274 $truefalse->question
= $new_question_id;
275 $truefalse->trueanswer
= backup_todb($tru_info['#']['TRUEANSWER']['0']['#']);
276 $truefalse->falseanswer
= backup_todb($tru_info['#']['FALSEANSWER']['0']['#']);
278 ////We have to recode the trueanswer field
279 $answer = backup_getid($restore->backup_unique_code
,"question_answers",$truefalse->trueanswer
);
281 $truefalse->trueanswer
= $answer->new_id
;
284 ////We have to recode the falseanswer field
285 $answer = backup_getid($restore->backup_unique_code
,"question_answers",$truefalse->falseanswer
);
287 $truefalse->falseanswer
= $answer->new_id
;
290 //The structure is equal to the db, so insert the question_truefalse
291 $newid = insert_record ("question_truefalse", $truefalse);
294 if (($i+
1) %
50 == 0) {
295 if (!defined('RESTORE_SILENTLY')) {
297 if (($i+
1) %
1000 == 0) {
312 function restore_recode_answer($state, $restore) {
313 //answer may be empty
314 if ($state->answer
) {
315 $answer = backup_getid($restore->backup_unique_code
,"question_answers",$state->answer
);
317 return $answer->new_id
;
319 echo 'Could not recode truefalse answer id '.$state->answer
.' for state '.$state->oldid
.'<br />';
325 //// END OF CLASS ////
327 //////////////////////////////////////////////////////////////////////////
328 //// INITIATION - Without this line the question type is not in use... ///
329 //////////////////////////////////////////////////////////////////////////
330 question_register_questiontype(new question_truefalse_qtype());