diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 8eb430ee2d7..d234fd8931c 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -252,30 +252,131 @@ function quiz_delete_instance($id) { return $result; } -function quiz_delete_course($course) { -/// 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-publish quiz categories and questions +/** + * 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) { - if ($categories = get_records_select("quiz_categories", "course = '$course->id' AND publish = '0'")) { - foreach ($categories as $category) { - if ($questions = get_records("quiz_questions", "category", $category->id)) { - foreach ($questions as $question) { - delete_records("quiz_answers", "question", $question->id); - delete_records("quiz_match", "question", $question->id); - delete_records("quiz_match_sub", "question", $question->id); - delete_records("quiz_multianswers", "question", $question->id); - delete_records("quiz_multichoice", "question", $question->id); - delete_records("quiz_numerical", "question", $question->id); - delete_records("quiz_randommatch", "question", $question->id); - delete_records("quiz_responses", "question", $question->id); - delete_records("quiz_shortanswer", "question", $question->id); - delete_records("quiz_truefalse", "question", $question->id); + global $CFG; + + //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('quiz_categories', 'course', $course->id, 'parent', 'id, parent, name, course')) { + require_once("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('quiz_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 (!$course->shortname) { + $course->shortname = $course->id .'('.get_string('deleted').')'; + } + $concat->name = get_string('savedfromdeletedcourse', 'quiz', $course->shortname); + $concat->info = $concat->name; + $concat->publish = 1; + $concat->stamp = make_unique_id_code(); + $concatid = insert_record('quiz_categories', $concat); + + //Fill feedback + $feedbackdata[] = array($concat->name, $strcatcontainer); } - delete_records("quiz_questions", "category", $category->id); + //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('quiz_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....not perfect until implemented in question classes (see bug 3366) + if ($questions = get_records("quiz_questions", "category", $category->id)) { + foreach ($questions as $question) { + delete_records("quiz_answers", "question", $question->id); + delete_records("quiz_match", "question", $question->id); + delete_records("quiz_match_sub", "question", $question->id); + delete_records("quiz_multianswers", "question", $question->id); + delete_records("quiz_multichoice", "question", $question->id); + delete_records("quiz_numerical", "question", $question->id); + delete_records("quiz_numerical_units", "question", $question->id); + delete_records("quiz_calculated", "question", $question->id); + delete_records("quiz_datasets", "question", $question->id); + delete_records("quiz_randomsamatch", "question", $question->id); + delete_records("quiz_shortanswer", "question", $question->id); + delete_records("quiz_truefalse", "question", $question->id); + delete_records("quiz_rqp", "question", $question->id); + delete_records("quiz_states", "question", $question->id); + delete_records("quiz_newest_states", "question", $question->id); + delete_records("quiz_question_versions", "oldquestion", $question->id); + delete_records("quiz_question_versions", "newquestion", $question->id); + } + delete_records("quiz_questions", "category", $category->id); + } + //delete the category + delete_records('quiz_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 ('quiz_categories', 'parent', $parentchanged[$category->id], 'parent', $category->id); + + //Fill feedback + $feedbackdata[] = array($category->name, $strcatdeleted); } } - return delete_records("quiz_categories", "course", $course->id); + //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; }