From f67172b64b3d456099995a05aad41da62afca6a0 Mon Sep 17 00:00:00 2001 From: gustav_delius Date: Tue, 21 Mar 2006 09:06:34 +0000 Subject: [PATCH] Moved code to delete questions and question categories to lib/questionlib.php Also fixed bug 4949 --- lib/moodlelib.php | 6 +- lib/questionlib.php | 177 ++++++++++++++++++++++++++++++++++++------ mod/quiz/lib.php | 125 +++-------------------------- mod/quiz/locallib.php | 32 -------- question/question.php | 2 +- 5 files changed, 170 insertions(+), 172 deletions(-) diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 805680cf8e..6be7cd8961 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -3170,7 +3170,7 @@ function remove_course_contents($courseid, $showfeedback=true) { } if (function_exists($moddeletecourse)) { - $moddeletecourse($course); + $moddeletecourse($course, $showfeedback); } } if ($showfeedback) { @@ -3257,6 +3257,10 @@ function remove_course_contents($courseid, $showfeedback=true) { } } + // Delete questions and question categories + include_once($CFG->libdir.'/questionlib.php'); + question_delete_course($course, $showfeedback); + return $result; } diff --git a/lib/questionlib.php b/lib/questionlib.php index ed629b1d42..8e02ea50e8 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -176,22 +176,56 @@ class cmoptions { /// FUNCTIONS ////////////////////////////////////////////////////// /** - * Returns an array with all the course modules that use this question + * Returns an array of names of activity modules that use this question * - * @param object $questionid + * @param object $questionid + * @return array of strings */ -function question_whereused($questionid) { +function question_list_instances($questionid) { $instances = array(); $modules = get_records('modules'); foreach ($modules as $module) { - $fn = $module->name.'_question_whereused'; + $fn = $module->name.'_question_list_instances'; if (function_exists($fn)) { - $instances[] = $fn($questionid); + $instances = $instances + $fn($questionid); } } return $instances; } +/** + * Tests whether a category is in use by any activity module + * + * @return boolean + * @param integer $categoryid + * @param boolean $recursive Whether to examine category children recursively + */ +function question_category_isused($categoryid, $recursive = false) { + + //Look at each question in the category + if ($questions = get_records('question', 'category', $categoryid)) { + foreach ($questions as $question) { + if (count(question_list_instances($question->id))) { + return true; + } + } + } + + //Look under child categories recursively + if ($recursive) { + if ($children = get_records('question_categories', 'parent', $categoryid)) { + foreach ($children as $child) { + if (question_category_isused($child->id, $recursive)) { + return true; + } + } + } + } + + return false; +} + + /** * Deletes question and all associated data from the database * @@ -202,7 +236,7 @@ function delete_question($questionid) { global $QTYPES; // Do not delete a question if it is used by an activity module - if (count(question_whereused($questionid))) { + if (count(question_list_instances($questionid))) { return; } @@ -230,6 +264,118 @@ function delete_question($questionid) { return; } +/** + * All non-used question categories and their questions are deleted and + * categories still used by other courses are moved to the site course. + * + * @param object $course an object representing the course + * @param boolean $feedback to specify if the process must output a summary of its work + * @return boolean + */ +function question_delete_course($course, $feedback=true) { + + global $CFG, $QTYPES; + + //To detect if we have created the "container category" + $concatid = 0; + + //The "container" category we'll create if we need if + $contcat = new object; + + //To temporary store changes performed with parents + $parentchanged = array(); + + //To store feedback to be showed at the end of the process + $feedbackdata = array(); + + //Cache some strings + $strcatcontainer=get_string('containercategorycreated', 'quiz'); + $strcatmoved = get_string('usedcategorymoved', 'quiz'); + $strcatdeleted = get_string('unusedcategorydeleted', 'quiz'); + + if ($categories = get_records('question_categories', 'course', $course->id, 'parent', 'id, parent, name, course')) { + + //Sort categories following their tree (parent-child) relationships + $categories = sort_categories_by_tree($categories); + + foreach ($categories as $cat) { + + //Get the full record + $category = get_record('question_categories', 'id', $cat->id); + + //Check if the category is being used anywhere + if(question_category_isused($category->id, true)) { + //It's being used. Cannot delete it, so: + //Create a container category in SITEID course if it doesn't exist + if (!$concatid) { + $concat->course = SITEID; + if (!isset($course->shortname)) { + $course->shortname = 'id=' . $course->id; + } + $concat->name = get_string('savedfromdeletedcourse', 'quiz', $course->shortname); + $concat->info = $concat->name; + $concat->publish = 1; + $concat->stamp = make_unique_id_code(); + $concatid = insert_record('question_categories', $concat); + + //Fill feedback + $feedbackdata[] = array($concat->name, $strcatcontainer); + } + //Move the category to the container category in SITEID course + $category->course = SITEID; + //Assign to container if the category hasn't parent or if the parent is wrong (not belongs to the course) + if (!$category->parent || !isset($categories[$category->parent])) { + $category->parent = $concatid; + } + //If it's being used, its publish field should be 1 + $category->publish = 1; + //Let's update it + update_record('question_categories', $category); + + //Save this parent change for future use + $parentchanged[$category->id] = $category->parent; + + //Fill feedback + $feedbackdata[] = array($category->name, $strcatmoved); + + } else { + //Category isn't being used so: + //Delete it completely (questions and category itself) + //deleting questions + if ($questions = get_records("question", "category", $category->id)) { + foreach ($questions as $question) { + delete_question($question->id); + } + delete_records("question", "category", $category->id); + } + //delete the category + delete_records('question_categories', 'id', $category->id); + + //Save this parent change for future use + if (!empty($category->parent)) { + $parentchanged[$category->id] = $category->parent; + } else { + $parentchanged[$category->id] = $concatid; + } + + //Update all its child categories to re-parent them to grandparent. + set_field ('question_categories', 'parent', $parentchanged[$category->id], 'parent', $category->id); + + //Fill feedback + $feedbackdata[] = array($category->name, $strcatdeleted); + } + } + //Inform about changes performed if feedback is enabled + if ($feedback) { + $table->head = array(get_string('category','quiz'), get_string('action')); + $table->data = $feedbackdata; + print_table($table); + } + } + return true; +} + + /** * Updates the question objects with question type specific * information by calling {@link get_question_options()} @@ -948,25 +1094,6 @@ function question_new_attempt_uniqueid() { return $CFG->attemptuniqueid; } -/** -* Array of names of course modules a question appears in -* -* TODO: Currently this works with quiz only -* -* @return array Array of quiz names -* @param integer $id Question id -*/ -function question_used($id) { - - $quizlist = array(); - if ($instances = get_records('quiz_question_instances', 'question', $id)) { - foreach($instances as $instance) { - $quizlist[$instance->quiz] = get_field('quiz', 'name', 'id', $instance->quiz); - } - } - - return $quizlist; -} /// FUNCTIONS THAT SIMPLY WRAP QUESTIONTYPE METHODS ////////////////////////////////// diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index d7932ef6f3..84990dd98c 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -11,6 +11,7 @@ */ require_once($CFG->libdir.'/pagelib.php'); +require_once($CFG->libdir.'/questionlib.php'); /// CONSTANTS /////////////////////////////////////////////////////////////////// @@ -294,119 +295,6 @@ function quiz_delete_instance($id) { return $result; } -/** - * Given a course object, this function will clean up anything that - * would be leftover after all the instances were deleted. - * In this case, all non-used quiz categories are deleted and - * used categories (by other courses) are moved to site course. - * - * @param object $course an object representing the course to be analysed - * @param boolean $feedback to specify if the process must output a summary of its work - * @return boolean - */ -function quiz_delete_course($course, $feedback=true) { - - global $CFG, $QTYPES; - - //To detect if we have created the "container category" - $concatid = 0; - - //The "container" category we'll create if we need if - $contcat = new object; - - //To temporary store changes performed with parents - $parentchanged = array(); - - //To store feedback to be showed at the end of the process - $feedbackdata = array(); - - //Cache some strings - $strcatcontainer=get_string('containercategorycreated', 'quiz'); - $strcatmoved = get_string('usedcategorymoved', 'quiz'); - $strcatdeleted = get_string('unusedcategorydeleted', 'quiz'); - - if ($categories = get_records('question_categories', 'course', $course->id, 'parent', 'id, parent, name, course')) { - require_once($CFG->dirroot.'/mod/quiz/locallib.php'); - //Sort categories following their tree (parent-child) relationships - $categories = sort_categories_by_tree($categories); - - foreach ($categories as $cat) { - - //Get the full record - $category = get_record('question_categories', 'id', $cat->id); - - //Check if the category is being used anywhere - if($usedbyquiz = quizzes_category_used($category->id,true)) { - //It's being used. Cannot delete it, so: - //Create a container category in SITEID course if it doesn't exist - if (!$concatid) { - $concat->course = SITEID; - if (!isset($course->shortname)) { - $course->shortname = 'id=' . $course->id; - } - $concat->name = get_string('savedfromdeletedcourse', 'quiz', $course->shortname); - $concat->info = $concat->name; - $concat->publish = 1; - $concat->stamp = make_unique_id_code(); - $concatid = insert_record('question_categories', $concat); - - //Fill feedback - $feedbackdata[] = array($concat->name, $strcatcontainer); - } - //Move the category to the container category in SITEID course - $category->course = SITEID; - //Assign to container if the category hasn't parent or if the parent is wrong (not belongs to the course) - if (!$category->parent || !isset($categories[$category->parent])) { - $category->parent = $concatid; - } - //If it's being used, its publish field should be 1 - $category->publish = 1; - //Let's update it - update_record('question_categories', $category); - - //Save this parent change for future use - $parentchanged[$category->id] = $category->parent; - - //Fill feedback - $feedbackdata[] = array($category->name, $strcatmoved); - - } else { - //Category isn't being used so: - //Delete it completely (questions and category itself) - //deleting questions - if ($questions = get_records("question", "category", $category->id)) { - foreach ($questions as $question) { - delete_question($question->id); - } - delete_records("question", "category", $category->id); - } - //delete the category - delete_records('question_categories', 'id', $category->id); - - //Save this parent change for future use - if (!empty($category->parent)) { - $parentchanged[$category->id] = $category->parent; - } else { - $parentchanged[$category->id] = $concatid; - } - - //Update all its child categories to re-parent them to grandparent. - set_field ('question_categories', 'parent', $parentchanged[$category->id], 'parent', $category->id); - - //Fill feedback - $feedbackdata[] = array($category->name, $strcatdeleted); - } - } - //Inform about changes performed if feedback is enabled - if ($feedback) { - $table->head = array(get_string('category','quiz'), get_string('action')); - $table->data = $feedbackdata; - print_table($table); - } - } - return true; -} - function quiz_user_outline($course, $user, $mod, $quiz) { /// Return a small object with summary information about what a @@ -791,4 +679,15 @@ function quiz_get_post_actions() { return array('attempt','editquestions','review','submit'); } +/** + * Returns an array of names of quizzes that use this question + * + * TODO: write this + * @param object $questionid + * @return array of strings + */ +function quiz_question_list_instances($questionid) { + return array(); +} + ?> diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 54ad9fbaee..952a838583 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -540,36 +540,4 @@ function quiz_get_reviewoptions($cmoptions, $attempt, $isteacher=false) { return $options; } - -/** -* Array of names of quizzes a category (and optionally its childs) appears in -* -* @return array Array of quiz names (with quiz->id as array keys) -* @param integer Quiz category id -* @param boolean Examine category childs recursively -*/ -function quizzes_category_used($id, $recursive = false) { - - $quizlist = array(); - - //Look for each question in the category - if ($questions = get_records('question', 'category', $id)) { - foreach ($questions as $question) { - $qlist = question_used($question->id); - $quizlist = $quizlist + $qlist; - } - } - - //Look under child categories recursively - if ($recursive) { - if ($childs = get_records('question_categories', 'parent', $id)) { - foreach ($childs as $child) { - $quizlist = $quizlist + quizzes_category_used($child->id, $recursive); - } - } - } - - return $quizlist; -} - ?> diff --git a/question/question.php b/question/question.php index 3a480f9e7a..fc5f52c2a1 100644 --- a/question/question.php +++ b/question/question.php @@ -133,7 +133,7 @@ } else { // TODO: check for other modules using this question - if ($quiznames = question_used($id)) { + if ($quiznames = question_list_instances($id)) { $a->questionname = $question->name; $a->quiznames = implode(', ', $quiznames); notify(get_string('questioninuse', 'quiz', $a)); -- 2.39.5