~ubuntu-branches/ubuntu/hoary/moodle/hoary

« back to all changes in this revision

Viewing changes to mod/quiz/questiontypes/match/questiontype.php

  • Committer: Bazaar Package Importer
  • Author(s): Isaac Clerencia
  • Date: 2004-12-29 00:49:52 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041229004952-gliyqzpj2w3e7clx
Tags: 1.4.3-1
* Urgency high as upstream release fixes several security bugs
* New upstream release
* Write database creation errors and warn the user about it, 
closes: #285842, #285842

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?PHP  // $Id: questiontype.php,v 1.2.2.1 2004/09/04 08:10:01 moodler Exp $
 
2
 
 
3
/////////////
 
4
/// MATCH ///
 
5
/////////////
 
6
 
 
7
/// QUESTION TYPE CLASS //////////////////
 
8
class quiz_match_qtype extends quiz_default_questiontype {
 
9
 
 
10
    function name() {
 
11
        return 'match';
 
12
    }
 
13
 
 
14
    function save_question_options($question) {
 
15
        
 
16
        if (!$oldsubquestions = get_records("quiz_match_sub", "question", $question->id, "id ASC")) {
 
17
            $oldsubquestions = array();
 
18
        }
 
19
 
 
20
        // following hack to check at least three answers exist
 
21
        $answercount = 0;
 
22
        foreach ($question->subquestions as $key=>$questiontext) {
 
23
            $answertext = $question->subanswers[$key];
 
24
            if (!empty($questiontext) and !empty($answertext)) {
 
25
                $answercount++;
 
26
            }
 
27
        }
 
28
        $answercount += count($oldsubquestions);
 
29
        if ($answercount < 3) { // check there are at lest 3 answers for matching type questions
 
30
            $result->notice = get_string("notenoughanswers", "quiz", "3");
 
31
            return $result;
 
32
        }
 
33
 
 
34
        $subquestions = array();
 
35
 
 
36
        // Insert all the new question+answer pairs
 
37
        foreach ($question->subquestions as $key => $questiontext) {
 
38
            $answertext = $question->subanswers[$key];
 
39
            if (!empty($questiontext) and !empty($answertext)) {
 
40
                if ($subquestion = array_shift($oldsubquestions)) {  // Existing answer, so reuse it
 
41
                    $subquestion->questiontext = $questiontext;
 
42
                    $subquestion->answertext   = $answertext;
 
43
                    if (!update_record("quiz_match_sub", $subquestion)) {
 
44
                        $result->error = "Could not insert quiz match subquestion! (id=$subquestion->id)";
 
45
                        return $result;
 
46
                    }
 
47
                } else {
 
48
                    unset($subquestion);
 
49
                    $subquestion->question = $question->id;
 
50
                    $subquestion->questiontext = $questiontext;
 
51
                    $subquestion->answertext   = $answertext;
 
52
                    if (!$subquestion->id = insert_record("quiz_match_sub", $subquestion)) {
 
53
                        $result->error = "Could not insert quiz match subquestion!";
 
54
                        return $result;
 
55
                    }
 
56
                }
 
57
                $subquestions[] = $subquestion->id;
 
58
            }
 
59
        }
 
60
 
 
61
        if (count($subquestions) < 3) {
 
62
            $result->noticeyesno = get_string("notenoughsubquestions", "quiz");
 
63
            return $result;
 
64
        }
 
65
 
 
66
        if ($options = get_record("quiz_match", "question", $question->id)) {
 
67
            $options->subquestions = implode(",",$subquestions);
 
68
            if (!update_record("quiz_match", $options)) {
 
69
                $result->error = "Could not update quiz match options! (id=$options->id)";
 
70
                return $result;
 
71
            }
 
72
        } else {
 
73
            unset($options);
 
74
            $options->question = $question->id;
 
75
            $options->subquestions = implode(",",$subquestions);
 
76
            if (!insert_record("quiz_match", $options)) {
 
77
                $result->error = "Could not insert quiz match options!";
 
78
                return $result;
 
79
            }
 
80
        }
 
81
        return true;
 
82
    }
 
83
    
 
84
    function convert_to_response_answer_field($questionresponse) {
 
85
    /// This method, together with extract_response, should be
 
86
    /// obsolete as soon as we get a better response storage
 
87
 
 
88
        $delimiter = '';
 
89
        $responseanswerfield = '';
 
90
        foreach ($questionresponse as $key => $value) {
 
91
            if ($matchid = $this->extract_response_id($key)) {
 
92
                $responseanswerfield .= "$delimiter$matchid-$value";
 
93
                $delimiter = ',';
 
94
            } else {
 
95
                notify("Error: Illegal match key $key detected");
 
96
            }
 
97
        }
 
98
        return $responseanswerfield;
 
99
    }
 
100
 
 
101
    function extract_response($rawresponse, $nameprefix) {
 
102
        if (!($options = get_record("quiz_match",
 
103
                                    "question", $rawresponse->question))) {
 
104
            notify("Error: Missing question options!");
 
105
            return array();
 
106
        }
 
107
        $subids = explode(',', $options->subquestions);
 
108
        foreach ($subids as $subid) {
 
109
            $response[$nameprefix.$subid] =
 
110
                    ereg("(^|,)$subid-([^,]+)", $rawresponse->answer, $regs)
 
111
                    ? $regs[2]
 
112
                    : '';
 
113
        }
 
114
        return $response;
 
115
    }
 
116
 
 
117
    function print_question_formulation_and_controls($question,
 
118
            $quiz, $readonly, $answers, $correctanswers, $nameprefix) {
 
119
 
 
120
        // Print question text and possible image
 
121
        if (!empty($question->questiontext)) {
 
122
            echo format_text($question->questiontext,
 
123
                             $question->questiontextformat,
 
124
                             NULL, $quiz->course);
 
125
        }
 
126
        quiz_print_possible_question_image($quiz->id, $question);
 
127
 
 
128
        // It so happens to be that $correctanswers for this question type also
 
129
        // contains the subqustions, which we need to make sure we have:
 
130
        if (empty($correctanswers)) {
 
131
            $options = get_record('quiz_match', 'question', $question->id)
 
132
            and $subquestions = get_records_list('quiz_match_sub', 'id',
 
133
                                                   $options->subquestions);
 
134
        } else {
 
135
            $subquestions = $correctanswers;
 
136
        }
 
137
 
 
138
        /// Check whether everything turned out alright:
 
139
        if (empty($subquestions)) {
 
140
            notify("Error: Missing subquestions for this question!");            
 
141
 
 
142
        } else {
 
143
            /// Everything is fine -
 
144
            /// Set up $subquestions and $answers and do the shuffling:
 
145
 
 
146
            if ($quiz->shuffleanswers) {
 
147
                $subquestions = draw_rand_array($subquestions,
 
148
                                                count($subquestions));
 
149
            }
 
150
            foreach ($subquestions as $key => $subquestion) {
 
151
                unset($answers[$key]);
 
152
                $answers[$subquestion->id] = $subquestion->answertext;
 
153
            }
 
154
            $answers = draw_rand_array($answers, count($answers));
 
155
        }
 
156
 
 
157
        ///// Ptint the input controls //////
 
158
 
 
159
        echo '<table border="0" cellpadding="10" align="right">';
 
160
        foreach ($subquestions as $subquestion) {
 
161
 
 
162
            /// Subquestion text:
 
163
            echo '<tr><td align="left" valign="top">';
 
164
            echo $subquestion->questiontext;
 
165
            echo '</td>';
 
166
 
 
167
            /// Drop-down list:
 
168
            $menuname = $nameprefix.$subquestion->id;
 
169
            $response = isset($question->response[$menuname])
 
170
                        ? $question->response[$menuname] : '0';
 
171
            if ($readonly 
 
172
                and $quiz->correctanswers 
 
173
                and isset($correctanswers[$menuname])
 
174
                and ($correctanswers[$menuname]->id == $response)) {
 
175
                $class = ' class="highlight" ';
 
176
            } else {
 
177
                $class = '';
 
178
            }
 
179
            echo "<td align=\"right\" valign=\"top\" $class>";
 
180
            choose_from_menu($answers, $menuname, $response);
 
181
            if ($quiz->feedback && isset($answers[$menuname])
 
182
                    && $answers[$menuname]->feedback) {
 
183
                quiz_print_comment($answers[$menuname]->feedback);
 
184
            }
 
185
            echo '</td></tr>';
 
186
        }
 
187
        echo '</table>';
 
188
    }
 
189
 
 
190
    function grade_response($question, $nameprefix) {
 
191
    /// This question type does not use the table quiz_answers
 
192
    /// but we will take some measures to emulate that record anyway.
 
193
 
 
194
        $result->grade = 0.0;
 
195
        $result->answers = array();
 
196
        $result->correctanswers = array();
 
197
 
 
198
        if (!($options = get_record('quiz_match', 'question', $question->id)
 
199
                and $subquestions = get_records_list('quiz_match_sub',
 
200
                                          'id', $options->subquestions))) {
 
201
            notify("Error: Cannot find match options and subquestions
 
202
                    for question $question->id");
 
203
            return $result;
 
204
        }
 
205
 
 
206
        $fraction = 1.0 / count($subquestions);
 
207
 
 
208
        /// Populate correctanswers arrays:
 
209
        foreach ($subquestions as $subquestion) {
 
210
            $subquestion->fraction = $fraction;
 
211
            $subquestion->answer = $subquestion->answertext;
 
212
            $subquestion->feedback = '';
 
213
            $result->correctanswers[$nameprefix.$subquestion->id] =
 
214
                    $subquestion;
 
215
        }
 
216
 
 
217
        foreach ($question->response as $responsekey => $answerid) {
 
218
 
 
219
            if ($answerid and $answer =
 
220
                    $result->correctanswers[$nameprefix.$answerid]) {
 
221
 
 
222
                if ($result->correctanswers[$responsekey]->answer
 
223
                        == $answer->answer) {
 
224
 
 
225
                    /// The response was correct!
 
226
                    $result->answers[$responsekey] =
 
227
                            $result->correctanswers[$responsekey];
 
228
                    $result->grade += $fraction;
 
229
 
 
230
                } else {
 
231
                    /// The response was incorrect:
 
232
                    $answer->fraction = 0.0;
 
233
                    $result->answers[$responsekey] = $answer;
 
234
                }
 
235
 
 
236
            }
 
237
        }
 
238
        return $result;
 
239
    }
 
240
}
 
241
//// END OF CLASS ////
 
242
 
 
243
//////////////////////////////////////////////////////////////////////////
 
244
//// INITIATION - Without this line the question type is not in use... ///
 
245
//////////////////////////////////////////////////////////////////////////
 
246
$QUIZ_QTYPES[MATCH]= new quiz_match_qtype();
 
247
 
 
248
?>