MDL-37082 core_course: create new course_delete_module function that handles the...
[moodle.git] / course / lib.php
index 92268fd..36dd31d 100644 (file)
@@ -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');
 
     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;
     }
         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);
         }
     }
         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');
         }
     }
         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
     // 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));
 
     $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);
     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);
     rebuild_course_cache($cm->course, true);
-    return true;
 }
 
 function delete_mod_from_section($modid, $sectionid) {
 }
 
 function delete_mod_from_section($modid, $sectionid) {