From 901c4aae9f53f56e90fca902f5cf064f25b2e9d0 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Thu, 27 Nov 2008 11:50:20 +0000 Subject: [PATCH] question bank: MDL-14434 Cannot edit the only question category in a context. --- lib/questionlib.php | 4 +-- question/category_class.php | 64 ++++++++++++++++++++----------------- question/category_form.php | 2 +- question/contextmove.php | 6 ++-- question/editlib.php | 33 ++++++++++++++----- 5 files changed, 65 insertions(+), 44 deletions(-) diff --git a/lib/questionlib.php b/lib/questionlib.php index 8cbb67dc310..14baef2cf77 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -2011,8 +2011,8 @@ function question_add_tops($categories, $pcontexts){ function question_categorylist($categoryid) { // returns a comma separated list of ids of the category and all subcategories $categorylist = $categoryid; - if ($subcategories = get_records('question_categories', 'parent', $categoryid, 'sortorder ASC', 'id, id')) { - foreach ($subcategories as $subcategory) { + if ($subcategories = get_records('question_categories', 'parent', $categoryid, 'sortorder ASC', 'id, 1 AS notused')) { + foreach ($ubcategories as $subcategory) { $categorylist .= ','. question_categorylist($subcategory->id); } } diff --git a/question/category_class.php b/question/category_class.php index ad372b482be..fe928d8fd06 100644 --- a/question/category_class.php +++ b/question/category_class.php @@ -389,7 +389,6 @@ class question_category_object { /** * Updates an existing category with given params - * */ function update_category($updateid, $newparent, $newname, $newinfo) { global $CFG, $QTYPES; @@ -397,47 +396,52 @@ class question_category_object { print_error('categorynamecantbeblank', 'quiz'); } - list($parentid, $tocontextid) = explode(',', $newparent); - + // Get the record we are updating. $oldcat = get_record('question_categories', 'id', $updateid); + $lastcategoryinthiscontext = question_is_only_toplevel_category_in_context($updateid); + + if (!empty($newparent) && !$lastcategoryinthiscontext) { + list($parentid, $tocontextid) = explode(',', $newparent); + } else { + $parentid = $oldcat->parent; + $tocontextid = $oldcat->contextid; + } + + // Check permissions. $fromcontext = get_context_instance_by_id($oldcat->contextid); require_capability('moodle/question:managecategory', $fromcontext); - if ($oldcat->contextid == $tocontextid){ + + // If moving to another context, check permissions some more. + if ($oldcat->contextid != $tocontextid){ $tocontext = get_context_instance_by_id($tocontextid); require_capability('moodle/question:managecategory', $tocontext); } + + // Update the category record. $cat = NULL; $cat->id = $updateid; $cat->name = $newname; $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 (addslashes($oldcat->name) != $cat->name) { - $randomqname = $QTYPES[RANDOM]->question_name($cat); - set_field('question', 'name', addslashes($randomqname), 'category', $cat->id, 'qtype', RANDOM); - // Ignore errors here. It is not a big deal if the questions are not renamed. - } + $cat->parent = $parentid; + // We don't change $cat->contextid here, if necessary we redirect to contextmove.php later. + if (!update_record("question_categories", $cat)) { + error("Could not update the category '$newname'", $this->pageurl->out()); + } - // Then update the category itself. - if ($oldcat->contextid == $tocontextid){ // not moving contexts - $cat->parent = $parentid; - if (!update_record("question_categories", $cat)) { - error("Could not update the category '$newname'", $this->pageurl->out()); - } else { - redirect($this->pageurl->out()); - } - } else { - if (!update_record("question_categories", $cat)) { - error("Could not update the category '$newname'", $this->pageurl->out()); - } else { - redirect($CFG->wwwroot.'/question/contextmove.php?'. - $this->pageurl->get_query_string(array('cattomove' => $updateid, - 'toparent'=>$newparent))); - } - } + // If the category name has changed, rename any random questions in that category. + if (addslashes($oldcat->name) != $cat->name) { + $randomqname = $QTYPES[RANDOM]->question_name($cat); + set_field('question', 'name', addslashes($randomqname), 'category', $cat->id, 'qtype', RANDOM); + // Ignore errors here. It is not a big deal if the questions are not renamed. + } + + // Then redirect to an appropriate place. + if ($oldcat->contextid == $tocontextid) { // not moving contexts + redirect($this->pageurl->out()); } else { - error("Cannot move the category '$newname'. It is the last in this context.", $this->pageurl->out()); + redirect($CFG->wwwroot.'/question/contextmove.php?' . + $this->pageurl->get_query_string(array( + 'cattomove' => $updateid, 'toparent'=>$newparent))); } } diff --git a/question/category_form.php b/question/category_form.php index b195b7130fe..e028d8319ca 100644 --- a/question/category_form.php +++ b/question/category_form.php @@ -16,7 +16,7 @@ class question_category_edit_form extends moodleform { $questioncategoryel = $mform->addElement('questioncategory', 'parent', get_string('parent', 'quiz'), array('contexts'=>$contexts, 'top'=>true, 'currentcat'=>$currentcat, 'nochildrenof'=>$currentcat)); $mform->setType('parent', PARAM_SEQUENCE); - if (1 == count_records_sql("SELECT count(*) FROM {$CFG->prefix}question_categories c1, {$CFG->prefix}question_categories c2 WHERE c2.id = $currentcat AND c1.contextid = c2.contextid")){ + if (question_is_only_toplevel_category_in_context($currentcat)){ $mform->hardFreeze('parent'); } $mform->setHelpButton('parent', array('categoryparent', get_string('parent', 'quiz'), 'question')); diff --git a/question/contextmove.php b/question/contextmove.php index 7ee59088357..695f80c1ae1 100644 --- a/question/contextmove.php +++ b/question/contextmove.php @@ -154,9 +154,9 @@ } //adjust sortorder before we make the cat a peer of it's new peers - $peers = get_records_select_menu('question_categories', "contextid = {$toparent->contextid} AND ". - "parent = {$toparent->id}", "sortorder ASC", - "id, id"); + $peers = get_records_select_menu('question_categories', + "contextid = {$toparent->contextid} AND parent = {$toparent->id}", + 'sortorder ASC', 'id, 1'); $peers = array_keys($peers); if ($totop){ array_unshift($peers, $cattomove->id); diff --git a/question/editlib.php b/question/editlib.php index 7445898cfc5..594a57d0965 100644 --- a/question/editlib.php +++ b/question/editlib.php @@ -76,17 +76,31 @@ function get_questions_category( $category, $noparent=false, $recurse=true, $exp return $qresults; } - -function question_can_delete_cat($todelete){ +/** + * @param integer $categoryid a category id. + * @return boolean whether this is the only top-level category in a context. + */ +function question_is_only_toplevel_category_in_context($categoryid) { global $CFG; - $record = get_record_sql("SELECT count(*) as count, c1.contextid as contextid FROM {$CFG->prefix}question_categories c1, - {$CFG->prefix}question_categories c2 WHERE c2.id = $todelete - AND c1.contextid = c2.contextid GROUP BY c1.contextid"); - $contextid = $record->contextid; - $count = $record->count; - if ($count < 2) { + return 1 == count_records_sql(" + SELECT count(*) + FROM {$CFG->prefix}question_categories c1, + {$CFG->prefix}question_categories c2 + WHERE c2.id = $categoryid + AND c1.contextid = c2.contextid + AND c1.parent = 0 AND c2.parent = 0"); +} + +/** + * Check whether this user is allowed to delete this category. + * + * @param integer $todelete a category id. + */ +function question_can_delete_cat($todelete) { + if (question_is_only_toplevel_category_in_context($todelete)) { error('You can\'t delete that category it is the default category for this context.'); } else { + $contextid = get_field('question_categories', 'contextid', 'id', $todelete); require_capability('moodle/question:managecategory', get_context_instance_by_id($contextid)); } } @@ -704,6 +718,9 @@ function question_edit_setup($edittab, $requirecmid = false, $requirecourseid = //category list page $pagevars['cpage'] = optional_param('cpage', 1, PARAM_INT); + if ($pagevars['cpage'] < 1) { + $pagevars['cpage'] = 1; + } if ($pagevars['cpage'] != 1){ $thispageurl->param('cpage', $pagevars['cpage']); }