Exemplo n.º 1
0
/**
 * This function will handle 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 Moodle 2.5
 */
function course_delete_module($cmid)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/questionlib.php';
    require_once $CFG->dirroot . '/blog/lib.php';
    require_once $CFG->dirroot . '/calendar/lib.php';
    // Get the course module.
    if (!($cm = $DB->get_record('course_modules', array('id' => $cmid)))) {
        return true;
    }
    // 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('cannotdeletemodulemissinglib', '', '', null, "Cannot delete this module as the file mod/{$modulename}/lib.php is missing.");
    }
    $deleteinstancefunction = $modulename . '_delete_instance';
    // Ensure the delete_instance function exists for this module.
    if (!function_exists($deleteinstancefunction)) {
        throw new moodle_exception('cannotdeletemodulemissingfunc', '', '', null, "Cannot delete this module as the function {$modulename}_delete_instance is missing in mod/{$modulename}/lib.php.");
    }
    // Delete activity context questions and question categories.
    question_delete_activity($cm);
    // Call the delete_instance function, if it returns false throw an exception.
    if (!$deleteinstancefunction($cm->instance)) {
        throw new moodle_exception('cannotdeletemoduleinstance', '', '', null, "Cannot delete the module {$modulename} (instance).");
    }
    // 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) {
            $calendarevent = calendar_event::load($event->id);
            $calendarevent->delete();
        }
    }
    // 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_completion_criteria', array('moduleinstance' => $cm->id, 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
    // Delete all tag instances associated with the instance of this module.
    core_tag_tag::delete_instances('mod_' . $modulename, null, $modcontext->id);
    core_tag_tag::remove_all_item_tags('core', 'course_modules', $cm->id);
    // Delete the context.
    context_helper::delete_instance(CONTEXT_MODULE, $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('cannotdeletemodulefromsection', '', '', null, "Cannot delete the module {$modulename} (instance) from section.");
    }
    // Trigger event for course module delete action.
    $event = \core\event\course_module_deleted::create(array('courseid' => $cm->course, 'context' => $modcontext, 'objectid' => $cm->id, 'other' => array('modulename' => $modulename, 'instanceid' => $cm->instance)));
    $event->add_record_snapshot('course_modules', $cm);
    $event->trigger();
    rebuild_course_cache($cm->course, true);
}
Exemplo n.º 2
0
/**
 * Deletes all the tag instances given a component and an optional contextid.
 *
 * @deprecated since 3.1
 * @param string $component
 * @param int $contextid if null, then we delete all tag instances for the $component
 */
function tag_delete_instances($component, $contextid = null)
{
    debugging('Method tag_delete() is deprecated, use core_tag_tag::delete_instances()', DEBUG_DEVELOPER);
    core_tag_tag::delete_instances($component, null, $contextid);
}
Exemplo n.º 3
0
 /**
  * Test the tag removed event.
  */
 public function test_tag_removed()
 {
     global $DB;
     $this->setAdminUser();
     // Create a course to tag.
     $course = $this->getDataGenerator()->create_course();
     // Create a wiki page to tag.
     $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
     $wiki = $wikigenerator->create_instance(array('course' => $course->id));
     $subwikiid = wiki_add_subwiki($wiki->id, 0);
     $wikipageid = wiki_create_page($subwikiid, 'Title', FORMAT_HTML, '2');
     // Create the tag.
     $tag = $this->getDataGenerator()->create_tag();
     // Assign a tag to a course.
     tag_assign('course', $course->id, $tag->id, 1, 2, 'core', context_course::instance($course->id)->id);
     $this->assertDebuggingCalled();
     // Trigger and capture the event for untagging a course.
     $sink = $this->redirectEvents();
     coursetag_delete_keyword($tag->id, 2, $course->id);
     $this->assertDebuggingCalled();
     $events = $sink->get_events();
     $event = reset($events);
     // Check that the tag was removed from the course and the event data is valid.
     $this->assertEquals(0, $DB->count_records('tag_instance'));
     $this->assertInstanceOf('\\core\\event\\tag_removed', $event);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     // Create the tag.
     $tag = $this->getDataGenerator()->create_tag();
     // Assign a tag to a wiki this time.
     tag_assign('wiki_pages', $wikipageid, $tag->id, 1, 2, 'mod_wiki', context_module::instance($wiki->cmid)->id);
     $this->assertDebuggingCalled();
     // Trigger and capture the event for deleting this tag instance.
     $sink = $this->redirectEvents();
     tag_delete_instance('wiki_pages', $wikipageid, $tag->id);
     $this->assertDebuggingCalled();
     $events = $sink->get_events();
     $event = reset($events);
     // Check that tag was removed from the wiki page and the event data is valid.
     $this->assertEquals(0, $DB->count_records('tag_instance'));
     $this->assertInstanceOf('\\core\\event\\tag_removed', $event);
     $this->assertEquals(context_module::instance($wiki->cmid), $event->get_context());
     // Create a tag again - the other would have been deleted since there were no more instances associated with it.
     $tag = $this->getDataGenerator()->create_tag();
     // Assign a tag to the wiki again.
     tag_assign('wiki_pages', $wikipageid, $tag->id, 1, 2, 'mod_wiki', context_module::instance($wiki->cmid)->id);
     $this->assertDebuggingCalled();
     // Now we want to delete this tag, and because there is only one tag instance
     // associated with it, it should get deleted as well.
     $sink = $this->redirectEvents();
     tag_delete($tag->id);
     $this->assertDebuggingCalled();
     $events = $sink->get_events();
     $event = reset($events);
     // Check that tag was removed from the wiki page and the event data is valid.
     $this->assertEquals(0, $DB->count_records('tag_instance'));
     $this->assertInstanceOf('\\core\\event\\tag_removed', $event);
     $this->assertEquals(context_module::instance($wiki->cmid), $event->get_context());
     // Create a tag again - the other would have been deleted since there were no more instances associated with it.
     $tag = $this->getDataGenerator()->create_tag();
     // Assign a tag to the wiki again.
     tag_assign('wiki_pages', $wikipageid, $tag->id, 1, 2, 'mod_wiki', context_module::instance($wiki->cmid)->id);
     $this->assertDebuggingCalled();
     // Delete all tag instances for this wiki instance.
     $sink = $this->redirectEvents();
     core_tag_tag::delete_instances('mod_wiki', 'wiki_pages', context_module::instance($wiki->cmid)->id);
     $events = $sink->get_events();
     $event = reset($events);
     // Check that tag was removed from the wiki page and the event data is valid.
     $this->assertEquals(0, $DB->count_records('tag_instance'));
     $this->assertInstanceOf('\\core\\event\\tag_removed', $event);
     $this->assertEquals(context_module::instance($wiki->cmid), $event->get_context());
     // Create another wiki.
     $wiki2 = $wikigenerator->create_instance(array('course' => $course->id));
     $subwikiid2 = wiki_add_subwiki($wiki2->id, 0);
     $wikipageid2 = wiki_create_page($subwikiid2, 'Title', FORMAT_HTML, '2');
     // Assign a tag to both wiki pages.
     tag_assign('wiki_pages', $wikipageid, $tag->id, 1, 2, 'mod_wiki', context_module::instance($wiki->cmid)->id);
     $this->assertDebuggingCalled();
     tag_assign('wiki_pages', $wikipageid2, $tag->id, 1, 2, 'mod_wiki', context_module::instance($wiki2->cmid)->id);
     $this->assertDebuggingCalled();
     // Now remove all tag_instances associated with all wikis.
     $sink = $this->redirectEvents();
     core_tag_tag::delete_instances('mod_wiki');
     $events = $sink->get_events();
     // There will be two events - one for each wiki instance removed.
     $event1 = reset($events);
     $event2 = $events[1];
     // Check that the tags were removed from the wiki pages.
     $this->assertEquals(0, $DB->count_records('tag_instance'));
     // Check the first event data is valid.
     $this->assertInstanceOf('\\core\\event\\tag_removed', $event1);
     $this->assertEquals(context_module::instance($wiki->cmid), $event1->get_context());
     // Check that the second event data is valid.
     $this->assertInstanceOf('\\core\\event\\tag_removed', $event2);
     $this->assertEquals(context_module::instance($wiki2->cmid), $event2->get_context());
 }
Exemplo n.º 4
0
 /**
  * Deletes all tag areas, collections and instances associated with the plugin.
  *
  * @param string $pluginname
  */
 public static function uninstall($pluginname)
 {
     global $DB;
     list($a, $b) = core_component::normalize_component($pluginname);
     if (empty($b) || $a === 'core') {
         throw new coding_exception('Core component can not be uninstalled');
     }
     $component = $a . '_' . $b;
     core_tag_tag::delete_instances($component);
     $DB->delete_records('tag_area', array('component' => $component));
     $DB->delete_records('tag_coll', array('component' => $component));
     cache::make('core', 'tags')->delete_many(array('tag_area', 'tag_coll'));
 }
Exemplo n.º 5
0
/**
 * This function will handle 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
 * @param bool $async whether or not to try to delete the module using an adhoc task. Async also depends on a plugin hook.
 * @throws moodle_exception
 * @since Moodle 2.5
 */
function course_delete_module($cmid, $async = false)
{
    // Check the 'course_module_background_deletion_recommended' hook first.
    // Only use asynchronous deletion if at least one plugin returns true and if async deletion has been requested.
    // Both are checked because plugins should not be allowed to dictate the deletion behaviour, only support/decline it.
    // It's up to plugins to handle things like whether or not they are enabled.
    if ($async && ($pluginsfunction = get_plugins_with_function('course_module_background_deletion_recommended'))) {
        foreach ($pluginsfunction as $plugintype => $plugins) {
            foreach ($plugins as $pluginfunction) {
                if ($pluginfunction()) {
                    return course_module_flag_for_async_deletion($cmid);
                }
            }
        }
    }
    global $CFG, $DB;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/questionlib.php';
    require_once $CFG->dirroot . '/blog/lib.php';
    require_once $CFG->dirroot . '/calendar/lib.php';
    // Get the course module.
    if (!($cm = $DB->get_record('course_modules', array('id' => $cmid)))) {
        return true;
    }
    // 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('cannotdeletemodulemissinglib', '', '', null, "Cannot delete this module as the file mod/{$modulename}/lib.php is missing.");
    }
    $deleteinstancefunction = $modulename . '_delete_instance';
    // Ensure the delete_instance function exists for this module.
    if (!function_exists($deleteinstancefunction)) {
        throw new moodle_exception('cannotdeletemodulemissingfunc', '', '', null, "Cannot delete this module as the function {$modulename}_delete_instance is missing in mod/{$modulename}/lib.php.");
    }
    // Allow plugins to use this course module before we completely delete it.
    if ($pluginsfunction = get_plugins_with_function('pre_course_module_delete')) {
        foreach ($pluginsfunction as $plugintype => $plugins) {
            foreach ($plugins as $pluginfunction) {
                $pluginfunction($cm);
            }
        }
    }
    // Delete activity context questions and question categories.
    question_delete_activity($cm);
    // Call the delete_instance function, if it returns false throw an exception.
    if (!$deleteinstancefunction($cm->instance)) {
        throw new moodle_exception('cannotdeletemoduleinstance', '', '', null, "Cannot delete the module {$modulename} (instance).");
    }
    // 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) {
            $calendarevent = calendar_event::load($event->id);
            $calendarevent->delete();
        }
    }
    // 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_completion_criteria', array('moduleinstance' => $cm->id, 'course' => $cm->course, 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
    // Delete all tag instances associated with the instance of this module.
    core_tag_tag::delete_instances('mod_' . $modulename, null, $modcontext->id);
    core_tag_tag::remove_all_item_tags('core', 'course_modules', $cm->id);
    // Notify the competency subsystem.
    \core_competency\api::hook_course_module_deleted($cm);
    // Delete the context.
    context_helper::delete_instance(CONTEXT_MODULE, $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('cannotdeletemodulefromsection', '', '', null, "Cannot delete the module {$modulename} (instance) from section.");
    }
    // Trigger event for course module delete action.
    $event = \core\event\course_module_deleted::create(array('courseid' => $cm->course, 'context' => $modcontext, 'objectid' => $cm->id, 'other' => array('modulename' => $modulename, 'instanceid' => $cm->instance)));
    $event->add_record_snapshot('course_modules', $cm);
    $event->trigger();
    rebuild_course_cache($cm->course, true);
}