Complete refactor of quiz_delete_course()

Now this function works following this:
- Iterate over every quiz category in the course (following parent-child relationships).
- If the category is being used*, move it to site level (under a container category) and
      mark it as published.
- If the category isn't being used, remove** it completely (questions, instances...) and
      re-parent its child categories.
- Feedback is shown in a table detailing all the changes performed.

* One category is being used if it has one question that is being used in any quiz,
  independently of its publish status.
** Removal of categories (and associated questions) has benn improved but, it won't
  be perfect until bug 3366 was solved.

Tested against some large courses with reused questions and multiple levels of
categories. Seems to work but

PLEASE TEST IT AND SEND ANY FEEDBACK TO BUG 2459
(http://moodle.org/bugs/bug.php?op=show&bugid=2459)

Exactly this function is going to be used in the upgrade script to solve
the orphan categories issue and it must work perfectly!

Merged from MOODLE_15_STABLE
This commit is contained in:
stronk7 2005-05-31 22:35:04 +00:00
parent a08e3a39a5
commit 9ea6ac5105

View File

@ -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;
}