1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
<?PHP // $Id: questiontype.php,v 1.2.2.1 2004/09/16 05:42:18 moodler Exp $
//////////////
/// RANDOM ///
//////////////
/// QUESTION TYPE CLASS //////////////////
class quiz_random_qtype extends quiz_default_questiontype {
var $possiblerandomqtypes = array(SHORTANSWER,
NUMERICAL,
MULTICHOICE,
MATCH,
// RANDOMSAMATCH,// Can cause unexpected outcomes
TRUEFALSE,
MULTIANSWER);
// Carries questions available as randoms sorted by category
// This array is used when needed only
var $catrandoms = array();
function name() {
return 'random';
}
function save_question_options($question) {
/// No options to be saved for this question type:
return true;
}
function wrapped_questions($question) {
global $QUIZ_QTYPES;
foreach ($question->response as $key => $response) {
if (ereg('[^0-9][0-9]+random$', $key)) {
$randomquestion = get_record('quiz_questions',
'id', $response);
$randomquestion->response = $question->response;
unset($randomquestion->response[$key]);
if ($subwrapped = $QUIZ_QTYPES[$randomquestion->qtype]
->wrapped_questions($randomquestion)) {
return "$response,$subwrapped";
} else {
return $response;
}
}
}
return false;
}
function convert_to_response_answer_field($questionresponse) {
/// THIS IS PART OF A WORKAROUND AS THIS IS THE ONLY
/// CASE WHERE IT IS NEEDED TO STORE TWO RESPONSE RECORDS...
global $QUIZ_QTYPES;
foreach ($questionresponse as $key => $response) {
if (ereg('[^0-9][0-9]+random$', $key)) {
unset($questionresponse[$key]);
$randomquestion = get_record('quiz_questions',
'id', $response);
return "random$response-"
.$QUIZ_QTYPES[$randomquestion->qtype]
->convert_to_response_answer_field($questionresponse);
}
}
return '';
}
function create_response($question, $nameprefix, $questionsinuse) {
// It's for question types like RANDOMSAMATCH and RANDOM that
// the true power of the pattern with this function comes to the surface.
// This implementation will stand even after a possible exclusion of
// the funtions extract_response and convert_to_response_answer_field
global $CFG;
if (!isset($this->catrandoms[$question->category])) {
//Need to fetch random questions from category $question->category"
$possiblerandomqtypes = "'"
. implode("','", $this->possiblerandomqtypes) . "'";
$this->catrandoms[$question->category] = get_records_sql
("SELECT * FROM {$CFG->prefix}quiz_questions
WHERE category = '$question->category'
AND id NOT IN ($questionsinuse)
AND qtype IN ($possiblerandomqtypes)");
$this->catrandoms[$question->category] =
draw_rand_array($this->catrandoms[$question->category],
count($this->catrandoms[$question->category])); // from bug 1889
}
while ($randomquestion =
array_pop($this->catrandoms[$question->category])) {
if (!ereg("(^|,)$randomquestion->id(,|$)", $questionsinuse)) {
/// $randomquestion is not in use and will therefore be used
/// as the randomquestion here...
global $QUIZ_QTYPES;
$response = $QUIZ_QTYPES[$randomquestion->qtype]
->create_response($randomquestion,
quiz_qtype_nameprefix($randomquestion, $nameprefix),
"$questionsinuse,$randomquestion->id");
$response[$nameprefix] = $randomquestion->id;
return $response;
}
}
notify(get_string('toomanyrandom', 'quiz', $question->category));
return array();
}
function extract_response($rawresponse, $nameprefix) {
global $QUIZ_QTYPES;
if ($randomquestion = get_record('quiz_questions',
'id', $rawresponse->answer)) {
if ($randomresponse = get_record
('quiz_responses', 'question', $rawresponse->answer,
'attempt', $rawresponse->attempt)) {
/// The prefered case:
// The response field for the random question was found
// the response array can be extracted:
$response = $QUIZ_QTYPES[$randomquestion->qtype]
->extract_response($randomresponse,
quiz_qtype_nameprefix($randomquestion, $nameprefix));
} else {
notify("Error: Cannot find response to random question $randomquestion->id");
/// Instead: workaround by creating a new response:
$response = $QUIZ_QTYPES[$randomquestion->qtype]
->create_response($randomquestion,
quiz_qtype_nameprefix($randomquestion, $nameprefix),
"$rawresponse->question,$rawresponse->answer");
// (That last argument is instead of $questionsinuse.
// It is not correct but it would be very messy to
// determine the correct value, while very few
// question types actually use it and they who do have
// good chances to execute properly anyway.)
}
$response[$nameprefix] = $randomquestion->id;
return $response;
} else {
notify("Error: Unable to find random question $rawresponse->question");
/// No new random question is picked as this is probably
/// not what the moodle user has in mind anyway
return array();
}
}
function print_question_formulation_and_controls($question,
$quiz, $readonly, $answers, $correctanswers, $nameprefix) {
global $QUIZ_QTYPES;
// Get the wrapped question...
if ($actualquestion = $this->get_wrapped_question($question,
$nameprefix)) {
echo '<input type="hidden" name="' . $nameprefix
. '" value="' . $actualquestion->id . '"/>';
return $QUIZ_QTYPES[$actualquestion->qtype]
->print_question_formulation_and_controls($actualquestion,
$quiz, $readonly, $answers, $correctanswers,
quiz_qtype_nameprefix($actualquestion, $nameprefix));
} else {
echo '<p>' . get_string('random', 'quiz') . '</p>';
}
}
function get_wrapped_question($question, $nameprefix) {
if (!empty($question->response[$nameprefix])
and $actualquestion = get_record('quiz_questions',
'id', $question->response[$nameprefix],
// The category check is a security check
'category', $question->category)) {
$actualquestion->response = $question->response;
unset($actualquestion->response[$nameprefix]);
$actualquestion->maxgrade = $question->maxgrade;
return $actualquestion;
} else {
return false;
}
}
function grade_response($question, $nameprefix) {
global $QUIZ_QTYPES;
// Get the wrapped question...
if ($actualquestion = $this->get_wrapped_question($question,
$nameprefix)) {
return $QUIZ_QTYPES[$actualquestion->qtype]->grade_response(
$actualquestion,
quiz_qtype_nameprefix($actualquestion, $nameprefix));
} else {
$result->grade = 0.0;
$result->answers = array();
$result->correctanswers = array();
return $result;
}
}
}
//// END OF CLASS ////
//////////////////////////////////////////////////////////////////////////
//// INITIATION - Without this line the question type is not in use... ///
//////////////////////////////////////////////////////////////////////////
$QUIZ_QTYPES[RANDOM]= new quiz_random_qtype();
?>
|