From a347aee32ea14f05ea7572b97684a52c90120556 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Mon, 10 Dec 2012 17:33:09 +0800 Subject: [PATCH] MDL-37082 core_course: create new course_delete_module function that handles the whole deletion process Instead of repeating code all over the place because the original function delete_course_module only partially deletes data, we now place all the functionality needed to delete a module here. --- course/dnduploadlib.php | 4 +- course/lib.php | 86 ++++++++++++++++++++++++++++++++------- course/mod.php | 42 ++----------------- course/rest.php | 39 +----------------- lib/deprecatedlib.php | 47 +++++++++++++++++++++ mod/assign/upgradelib.php | 58 +------------------------- 6 files changed, 126 insertions(+), 150 deletions(-) diff --git a/course/dnduploadlib.php b/course/dnduploadlib.php index ecb519bbabc..73c8a79ce0f 100644 --- a/course/dnduploadlib.php +++ b/course/dnduploadlib.php @@ -616,7 +616,7 @@ class dndupload_ajax_processor { if (!$instanceid) { // Something has gone wrong - undo everything we can. - delete_course_module($this->cm->id); + course_delete_module($this->cm->id); throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); } @@ -639,7 +639,7 @@ class dndupload_ajax_processor { $info = get_fast_modinfo($this->course); if (!isset($info->cms[$this->cm->id])) { // The course module has not been properly created in the course - undo everything. - delete_course_module($this->cm->id); + course_delete_module($this->cm->id); throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); } $mod = $info->get_cm($this->cm->id); diff --git a/course/lib.php b/course/lib.php index 92268fdf938..36dd31df6f9 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2183,46 +2183,102 @@ function set_coursemodule_visible($id, $visible) { } /** - * Delete a course module and any associated data at the course level (events) - * Until 1.5 this function simply marked a deleted flag ... now it - * deletes it completely. + * This function will handles the whole deletion process of a module. This includes calling + * the modules delete_instance function, deleting files, events, grades, conditional data, + * the data in the course_module and course_sections table and adding a module deletion + * event to the DB. * + * @param int $cmid the course module id + * @since 2.5 */ -function delete_course_module($id) { - global $CFG, $DB; +function course_delete_module($cmid) { + global $CFG, $DB, $USER; + require_once($CFG->libdir.'/gradelib.php'); require_once($CFG->dirroot.'/blog/lib.php'); - if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) { + // Get the course module. + if (!$cm = $DB->get_record('course_modules', array('id' => $cmid))) { return true; } - $modulename = $DB->get_field('modules', 'name', array('id'=>$cm->module)); - //delete events from calendar - if ($events = $DB->get_records('event', array('instance'=>$cm->instance, 'modulename'=>$modulename))) { + + // Get the module context. + $modcontext = context_module::instance($cm->id); + + // Get the course module name. + $modulename = $DB->get_field('modules', 'name', array('id' => $cm->module), MUST_EXIST); + + // Get the file location of the delete_instance function for this module. + $modlib = "$CFG->dirroot/mod/$modulename/lib.php"; + + // Include the file required to call the delete_instance function for this module. + if (file_exists($modlib)) { + require_once($modlib); + } else { + throw new moodle_exception("This module is missing mod/$modulename/lib.php", '', '', + null, 'failedtodeletemodulemissinglibfile'); + } + + $deleteinstancefunction = $modulename . "_delete_instance"; + + if (!$deleteinstancefunction($cm->instance)) { + throw new moodle_exception("Could not delete the $modulename (instance)", '', '', + null, 'failedtodeletemoduleinstance'); + } + + // Remove all module files in case modules forget to do that. + $fs = get_file_storage(); + $fs->delete_area_files($modcontext->id); + + // Delete events from calendar. + if ($events = $DB->get_records('event', array('instance' => $cm->instance, 'modulename' => $modulename))) { foreach($events as $event) { delete_event($event->id); } } - //delete grade items, outcome items and grades attached to modules - if ($grade_items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename, - 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course))) { + + // Delete grade items, outcome items and grades attached to modules. + if ($grade_items = grade_item::fetch_all(array('itemtype' => 'mod', 'itemmodule' => $modulename, + 'iteminstance' => $cm->instance, 'courseid' => $cm->course))) { foreach ($grade_items as $grade_item) { $grade_item->delete('moddelete'); } } + // Delete completion and availability data; it is better to do this even if the // features are not turned on, in case they were turned on previously (these will be - // very quick on an empty table) + // very quick on an empty table). $DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id)); $DB->delete_records('course_modules_availability', array('coursemoduleid'=> $cm->id)); $DB->delete_records('course_modules_avail_fields', array('coursemoduleid' => $cm->id)); $DB->delete_records('course_completion_criteria', array('moduleinstance' => $cm->id, 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY)); + // Delete the context. delete_context(CONTEXT_MODULE, $cm->id); - $DB->delete_records('course_modules', array('id'=>$cm->id)); + + // Delete the module from the course_modules table. + $DB->delete_records('course_modules', array('id' => $cm->id)); + + // Delete module from that section. + if (!delete_mod_from_section($cm->id, $cm->section)) { + throw new moodle_exception("Could not delete the $modulename from section", '', '', + null, 'failedtodeletemodulefromsection'); + } + + // Trigger a mod_deleted event with information about this module. + $eventdata = new stdClass(); + $eventdata->modulename = $modulename; + $eventdata->cmid = $cm->id; + $eventdata->courseid = $cm->course; + $eventdata->userid = $USER->id; + events_trigger('mod_deleted', $eventdata); + + add_to_log($cm->course, 'course', "delete mod", + "view.php?id=$cm->course", + "$modulename $cm->instance", $cm->id); + rebuild_course_cache($cm->course, true); - return true; } function delete_mod_from_section($modid, $sectionid) { diff --git a/course/mod.php b/course/mod.php index b1ed6171d8b..1ea8b78cc8c 100644 --- a/course/mod.php +++ b/course/mod.php @@ -120,7 +120,6 @@ if (!empty($add)) { $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_login($course, false, $cm); - $coursecontext = context_course::instance($course->id); $modcontext = context_module::instance($cm->id); require_capability('moodle/course:manageactivities', $modcontext); @@ -138,9 +137,8 @@ if (!empty($add)) { $PAGE->set_title($strdeletecheck); $PAGE->set_heading($course->fullname); $PAGE->navbar->add($strdeletecheck); - echo $OUTPUT->header(); - // print_simple_box_start('center', '60%', '#FFAAAA', 20, 'noticebox'); + echo $OUTPUT->header(); echo $OUTPUT->box_start('noticebox'); $formcontinue = new single_button(new moodle_url("$CFG->wwwroot/course/mod.php", $optionsyes), get_string('yes')); $formcancel = new single_button($return, get_string('no'), 'get'); @@ -151,42 +149,8 @@ if (!empty($add)) { exit; } - $modlib = "$CFG->dirroot/mod/$cm->modname/lib.php"; - - if (file_exists($modlib)) { - require_once($modlib); - } else { - print_error('modulemissingcode', '', '', $modlib); - } - - $deleteinstancefunction = $cm->modname."_delete_instance"; - - if (!$deleteinstancefunction($cm->instance)) { - echo $OUTPUT->notification("Could not delete the $cm->modname (instance)"); - } - - // remove all module files in case modules forget to do that - $fs = get_file_storage(); - $fs->delete_area_files($modcontext->id); - - if (!delete_course_module($cm->id)) { - echo $OUTPUT->notification("Could not delete the $cm->modname (coursemodule)"); - } - if (!delete_mod_from_section($cm->id, $cm->section)) { - echo $OUTPUT->notification("Could not delete the $cm->modname from that section"); - } - - // Trigger a mod_deleted event with information about this module. - $eventdata = new stdClass(); - $eventdata->modulename = $cm->modname; - $eventdata->cmid = $cm->id; - $eventdata->courseid = $course->id; - $eventdata->userid = $USER->id; - events_trigger('mod_deleted', $eventdata); - - add_to_log($course->id, 'course', "delete mod", - "view.php?id=$cm->course", - "$cm->modname $cm->instance", $cm->id); + // Delete the module. + course_delete_module($cm->id); redirect($return); } diff --git a/course/rest.php b/course/rest.php index 8056c57eb52..3e389c60cd7 100644 --- a/course/rest.php +++ b/course/rest.php @@ -194,44 +194,7 @@ switch($requestmethod) { switch ($class) { case 'resource': require_capability('moodle/course:manageactivities', $modcontext); - $modlib = "$CFG->dirroot/mod/$cm->modname/lib.php"; - - if (file_exists($modlib)) { - include_once($modlib); - } else { - throw new moodle_exception("Ajax rest.php: This module is missing mod/$cm->modname/lib.php"); - } - $deleteinstancefunction = $cm->modname."_delete_instance"; - - // Run the module's cleanup funtion. - if (!$deleteinstancefunction($cm->instance)) { - throw new moodle_exception("Ajax rest.php: Could not delete the $cm->modname $cm->name (instance)"); - die; - } - - // remove all module files in case modules forget to do that - $fs = get_file_storage(); - $fs->delete_area_files($modcontext->id); - - if (!delete_course_module($cm->id)) { - throw new moodle_exception("Ajax rest.php: Could not delete the $cm->modname $cm->name (coursemodule)"); - } - // Remove the course_modules entry. - if (!delete_mod_from_section($cm->id, $cm->section)) { - throw new moodle_exception("Ajax rest.php: Could not delete the $cm->modname $cm->name from section"); - } - - // Trigger a mod_deleted event with information about this module. - $eventdata = new stdClass(); - $eventdata->modulename = $cm->modname; - $eventdata->cmid = $cm->id; - $eventdata->courseid = $course->id; - $eventdata->userid = $USER->id; - events_trigger('mod_deleted', $eventdata); - - add_to_log($courseid, "course", "delete mod", - "view.php?id=$courseid", - "$cm->modname $cm->instance", $cm->id); + course_delete_module($cm->id); break; } break; diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 327b03d48ed..21087709721 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -3437,3 +3437,50 @@ function print_recent_activity($course) { echo '

'.get_string('nothingnew').'

'; } } + +/** + * Delete a course module and any associated data at the course level (events) + * Until 1.5 this function simply marked a deleted flag ... now it + * deletes it completely. + * + * @deprecated since 2.5 + * + * @param int $id the course module id + * @return boolean true on success, false on failure + */ +function delete_course_module($id) { + debugging('Function delete_course_module() is deprecated. Please use course_delete_module() instead.', DEBUG_DEVELOPER); + + global $CFG, $DB; + + require_once($CFG->libdir.'/gradelib.php'); + require_once($CFG->dirroot.'/blog/lib.php'); + + if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) { + return true; + } + $modulename = $DB->get_field('modules', 'name', array('id'=>$cm->module)); + //delete events from calendar + if ($events = $DB->get_records('event', array('instance'=>$cm->instance, 'modulename'=>$modulename))) { + foreach($events as $event) { + delete_event($event->id); + } + } + //delete grade items, outcome items and grades attached to modules + if ($grade_items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename, + 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course))) { + foreach ($grade_items as $grade_item) { + $grade_item->delete('moddelete'); + } + } + // Delete completion and availability data; it is better to do this even if the + // features are not turned on, in case they were turned on previously (these will be + // very quick on an empty table) + $DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id)); + $DB->delete_records('course_modules_availability', array('coursemoduleid'=> $cm->id)); + $DB->delete_records('course_completion_criteria', array('moduleinstance' => $cm->id, + 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY)); + + delete_context(CONTEXT_MODULE, $cm->id); + return $DB->delete_records('course_modules', array('id'=>$cm->id)); +} diff --git a/mod/assign/upgradelib.php b/mod/assign/upgradelib.php index 055457bef2c..f91e88a798f 100644 --- a/mod/assign/upgradelib.php +++ b/mod/assign/upgradelib.php @@ -26,6 +26,7 @@ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot.'/mod/assign/locallib.php'); require_once($CFG->libdir.'/accesslib.php'); +require_once($CFG->dirroot.'/course/lib.php'); /* * The maximum amount of time to spend upgrading a single assignment. @@ -326,7 +327,7 @@ class assign_upgrade_manager { // Delete the old assignment (use object delete). $cm = get_coursemodule_from_id('', $oldcoursemodule->id, $oldcoursemodule->course); if ($cm) { - $this->delete_course_module($cm); + course_delete_module($cm->id); } rebuild_course_cache($oldcoursemodule->course); return true; @@ -385,59 +386,4 @@ class assign_upgrade_manager { return $newcm; } - - /** - * This function deletes the old assignment course module after - * it has been upgraded. This code is adapted from "course/mod.php". - * - * @param stdClass $cm The course module to delete. - * @return bool - */ - private function delete_course_module($cm) { - global $CFG, $USER, $DB, $OUTPUT; - $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); - - $coursecontext = context_course::instance($course->id); - $modcontext = context_module::instance($cm->id); - - $modlib = "$CFG->dirroot/mod/$cm->modname/lib.php"; - - if (file_exists($modlib)) { - require_once($modlib); - } else { - print_error('modulemissingcode', '', '', $modlib); - } - - $deleteinstancefunction = $cm->modname."_delete_instance"; - - if (!$deleteinstancefunction($cm->instance)) { - echo $OUTPUT->notification("Could not delete the $cm->modname (instance)"); - } - - // Remove all module files in case modules forget to do that. - $fs = get_file_storage(); - $fs->delete_area_files($modcontext->id); - - if (!delete_course_module($cm->id)) { - echo $OUTPUT->notification("Could not delete the $cm->modname (coursemodule)"); - } - if (!delete_mod_from_section($cm->id, $cm->section)) { - echo $OUTPUT->notification("Could not delete the $cm->modname from that section"); - } - - // Trigger a mod_deleted event with information about this module. - $eventdata = new stdClass(); - $eventdata->modulename = $cm->modname; - $eventdata->cmid = $cm->id; - $eventdata->courseid = $course->id; - $eventdata->userid = $USER->id; - events_trigger('mod_deleted', $eventdata); - - add_to_log($course->id, 'course', "delete mod", - "view.php?id=$cm->course", - "$cm->modname $cm->instance", $cm->id); - - return true; - } - } -- 2.43.0