* Don't let the user set the name for random questions.
* Instead force the name to be "Random (catname)" (localised) whever the question is created or saved.
* When a category is renamed, rename all the random questions in it.
* Remove the restriction that Jamie seems to have added in 1.9 that was preventing the category of random questions from being edited.
$catcontext = get_context_instance_by_id($category->contextid);
require_capability('moodle/question:useall', $catcontext);
$category->name = addslashes($category->name);
- // find existing random questions in this category
- $random = RANDOM;
- if ($existingquestions = get_records_select('question', "qtype = '$random' AND category = '$category->id'")) {
- // now remove the ones that are already used in this quiz
- if ($questionids = explode(',', $quiz->questions)) {
- foreach ($questionids as $questionid) {
- unset($existingquestions[$questionid]);
- }
- }
- // now take as many of these as needed
- $i = 0;
- while (($existingquestion = array_pop($existingquestions)) and ($i < $randomcount)) {
- if ($existingquestion->questiontext == $recurse) {
- // this question has the right recurse property, so use it
- quiz_add_quiz_question($existingquestion->id, $quiz);
- $i++;
- }
+ // Find existing random questions in this category that are not used by any quiz.
+ if ($existingquestions = get_records_sql(
+ "SELECT * FROM " . $CFG->prefix . "question q
+ WHERE qtype = '" . RANDOM . "'
+ AND category = $category->id
+ AND " . sql_compare_text('questiontext') . " = '$recurse'
+ AND NOT EXISTS (SELECT * FROM " . $CFG->prefix . "quiz_question_instances WHERE question = q.id)
+ ORDER BY id")) {
+ // Take as many of these as needed.
+ while (($existingquestion = array_shift($existingquestions)) and $randomcount > 0) {
+ quiz_add_quiz_question($existingquestion->id, $quiz);
+ $randomcount--;
}
- $randomcreate = $randomcount - $i; // the number of additional random questions needed.
- } else {
- $randomcreate = $randomcount;
}
- if ($randomcreate > 0) {
-
- $form->name = get_string('random', 'quiz') .' ('. $category->name .')';
- $form->category = "$category->id,$category->contextid";
+ // If more are needed, create them.
+ if ($randomcount > 0) {
$form->questiontext = $recurse; // we use the questiontext field to store the info
// on whether to include questions in subcategories
$form->questiontextformat = 0;
$form->image = '';
$form->defaultgrade = 1;
$form->hidden = 1;
- for ($i=0; $i<$randomcreate; $i++) {
+ for ($i = 0; $i < $randomcount; $i++) {
+ $form->category = "$category->id,$category->contextid";
$form->stamp = make_unique_id_code(); // Set the unique code (not to be changed)
$question = new stdClass;
$question->qtype = RANDOM;
$cat->info = $newinfo;
//never move category where it is the default
if (1 != count_records_sql("SELECT count(*) FROM {$CFG->prefix}question_categories c1, {$CFG->prefix}question_categories c2 WHERE c2.id = $updateid AND c1.contextid = c2.contextid")){
+ // If the question name has changed, rename any random questions in that category.
+ if ($oldcat->name != $cat->name) {
+ $randomqname = $QTYPES[RANDOM]->question_name($cat);
+ set_field('question', 'name', $randomqname, 'category', $cat->id, 'qtype', RANDOM);
+ // Ignore errors here. It is not a big deal if the questions are not renamed.
+ }
+
+ // Then update the category itself.
if ($oldcat->contextid == $tocontextid){ // not moving contexts
$cat->parent = $parentid;
if (!update_record("question_categories", $cat)) {
if (!empty($question->id)) { // Question already exists
if (isset($form->categorymoveto)){
question_require_capability_on($question, 'move');
- list($question->categorymoveto, $movetocontextid) = explode(',', $form->categorymoveto);
+ list($question->category, $movetocontextid) = explode(',', $form->categorymoveto);
//don't need to test add permission of category we are moving question to.
//Only categories that we have permission to add
//a question to will get through the form cleaning code for the select box.
- if (isset($question->qtype) && $question->qtype != RANDOM){
- $question->category = $question->categorymoveto;
- }
}
// keep existing unique stamp code
$question->stamp = get_field('question', 'stamp', 'id', $question->id);
$mform->addElement('questioncategory', 'category', get_string('category', 'quiz'),
array('contexts' => $this->contexts->having_cap('moodle/question:useall')));
- $mform->addElement('text', 'name', get_string('questionname', 'quiz'),
- array('size' => 50));
- $mform->setType('name', PARAM_TEXT);
- $mform->addRule('name', null, 'required', null, 'client');
-
$mform->addElement('advcheckbox', 'questiontext', get_string("recurse", "quiz"), null, null, array(0, 1));
// Standard fields at the end of the form.
$mform->closeHeaderBefore('buttonar');
}
- function set_data($question) {
- if (empty($question->name)) {
- $question->name = get_string("random", "quiz");
- }
- parent::set_data($question);
- }
-
function qtype() {
return 'random';
}
return true;
}
+ /**
+ * Random questions always get a question name that is Random (cateogryname).
+ * This function is a centralised place to calculate that, given the category.
+ */
+ function question_name($category) {
+ return get_string('random', 'quiz') .' ('. $category->name .')';
+ }
+
+ function save_question($question, $form, $course) {
+ // If the category is changing, set things up as default_questiontype::save_question expects.
+ list($formcategory, $unused) = explode(',', $form->category);
+ if (isset($question->id) && $formcategory != $question->category) {
+ $form->categorymoveto = $form->category;
+ }
+ $form->name = '';
+ $question = parent::save_question($question, $form, $course);
+ if (!$category = get_record('question_categories', 'id', $question->category)) {
+ error('Could retrieve question category');
+ }
+ $question->name = $this->question_name($category);
+ if (!set_field('question', 'name', $question->name, 'id', $question->id)) {
+ error('Could not update random question name');
+ }
+ return $question;
+ }
+
function save_question_options($question) {
// No options, but we set the parent field to the question's own id.
// Setting the parent field has the effect of hiding this question in