コード例 #1
0
ファイル: adminlib.php プロジェクト: Alexbado/moodle2
/**
 * Automatically clean-up all plugin data and remove the plugin DB tables
 *
 * NOTE: do not call directly, use new /admin/plugins.php?uninstall=component instead!
 *
 * @param string $type The plugin type, eg. 'mod', 'qtype', 'workshopgrading' etc.
 * @param string $name The plugin name, eg. 'forum', 'multichoice', 'accumulative' etc.
 * @uses global $OUTPUT to produce notices and other messages
 * @return void
 */
function uninstall_plugin($type, $name)
{
    global $CFG, $DB, $OUTPUT;
    // This may take a long time.
    core_php_time_limit::raise();
    // Recursively uninstall all subplugins first.
    $subplugintypes = core_component::get_plugin_types_with_subplugins();
    if (isset($subplugintypes[$type])) {
        $base = core_component::get_plugin_directory($type, $name);
        if (file_exists("{$base}/db/subplugins.php")) {
            $subplugins = array();
            include "{$base}/db/subplugins.php";
            foreach ($subplugins as $subplugintype => $dir) {
                $instances = core_component::get_plugin_list($subplugintype);
                foreach ($instances as $subpluginname => $notusedpluginpath) {
                    uninstall_plugin($subplugintype, $subpluginname);
                }
            }
        }
    }
    $component = $type . '_' . $name;
    // eg. 'qtype_multichoice' or 'workshopgrading_accumulative' or 'mod_forum'
    if ($type === 'mod') {
        $pluginname = $name;
        // eg. 'forum'
        if (get_string_manager()->string_exists('modulename', $component)) {
            $strpluginname = get_string('modulename', $component);
        } else {
            $strpluginname = $component;
        }
    } else {
        $pluginname = $component;
        if (get_string_manager()->string_exists('pluginname', $component)) {
            $strpluginname = get_string('pluginname', $component);
        } else {
            $strpluginname = $component;
        }
    }
    echo $OUTPUT->heading($pluginname);
    // Delete all tag instances associated with this plugin.
    require_once $CFG->dirroot . '/tag/lib.php';
    tag_delete_instances($component);
    // Custom plugin uninstall.
    $plugindirectory = core_component::get_plugin_directory($type, $name);
    $uninstalllib = $plugindirectory . '/db/uninstall.php';
    if (file_exists($uninstalllib)) {
        require_once $uninstalllib;
        $uninstallfunction = 'xmldb_' . $pluginname . '_uninstall';
        // eg. 'xmldb_workshop_uninstall()'
        if (function_exists($uninstallfunction)) {
            // Do not verify result, let plugin complain if necessary.
            $uninstallfunction();
        }
    }
    // Specific plugin type cleanup.
    $plugininfo = core_plugin_manager::instance()->get_plugin_info($component);
    if ($plugininfo) {
        $plugininfo->uninstall_cleanup();
        core_plugin_manager::reset_caches();
    }
    $plugininfo = null;
    // perform clean-up task common for all the plugin/subplugin types
    //delete the web service functions and pre-built services
    require_once $CFG->dirroot . '/lib/externallib.php';
    external_delete_descriptions($component);
    // delete calendar events
    $DB->delete_records('event', array('modulename' => $pluginname));
    // Delete scheduled tasks.
    $DB->delete_records('task_scheduled', array('component' => $pluginname));
    // Delete Inbound Message datakeys.
    $DB->delete_records_select('messageinbound_datakeys', 'handler IN (SELECT id FROM {messageinbound_handlers} WHERE component = ?)', array($pluginname));
    // Delete Inbound Message handlers.
    $DB->delete_records('messageinbound_handlers', array('component' => $pluginname));
    // delete all the logs
    $DB->delete_records('log', array('module' => $pluginname));
    // delete log_display information
    $DB->delete_records('log_display', array('component' => $component));
    // delete the module configuration records
    unset_all_config_for_plugin($component);
    if ($type === 'mod') {
        unset_all_config_for_plugin($pluginname);
    }
    // delete message provider
    message_provider_uninstall($component);
    // delete the plugin tables
    $xmldbfilepath = $plugindirectory . '/db/install.xml';
    drop_plugin_tables($component, $xmldbfilepath, false);
    if ($type === 'mod' or $type === 'block') {
        // non-frankenstyle table prefixes
        drop_plugin_tables($name, $xmldbfilepath, false);
    }
    // delete the capabilities that were defined by this module
    capabilities_cleanup($component);
    // remove event handlers and dequeue pending events
    events_uninstall($component);
    // Delete all remaining files in the filepool owned by the component.
    $fs = get_file_storage();
    $fs->delete_component_files($component);
    // Finally purge all caches.
    purge_all_caches();
    // Invalidate the hash used for upgrade detections.
    set_config('allversionshash', '');
    echo $OUTPUT->notification(get_string('success'), 'notifysuccess');
}
コード例 #2
0
ファイル: lib.php プロジェクト: uniedpa/moodle
/**
 * 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';
    require_once $CFG->dirroot . '/tag/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.
    tag_delete_instances('mod_' . $modulename, $modcontext->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);
}
コード例 #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);
     // Trigger and capture the event for untagging a course.
     $sink = $this->redirectEvents();
     coursetag_delete_keyword($tag->id, 2, $course->id);
     $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);
     // Trigger and capture the event for deleting this tag instance.
     $sink = $this->redirectEvents();
     tag_delete_instance('wiki_pages', $wikipageid, $tag->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 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);
     // 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);
     $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);
     // Delete all tag instances for this wiki instance.
     $sink = $this->redirectEvents();
     tag_delete_instances('mod_wiki', 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);
     tag_assign('wiki_pages', $wikipageid2, $tag->id, 1, 2, 'mod_wiki', context_module::instance($wiki2->cmid)->id);
     // Now remove all tag_instances associated with all wikis.
     $sink = $this->redirectEvents();
     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());
 }
コード例 #4
0
 /**
  * Called by delete_instance. Deletes all the forum's data (but
  * not the actual forum record, delete_instance handles that).
  */
 public function delete_all_data()
 {
     global $DB, $CFG;
     require_once $CFG->dirroot . '/tag/lib.php';
     // Delete per-post data
     $postquery = "\nSELECT\n    fp.id\nFROM\n    {forumng_discussions} fd\n    INNER JOIN {forumng_posts} fp on fp.discussionid = fd.id\nWHERE\n    fd.forumngid = ?";
     $postparams = array($this->forumfields->id);
     $DB->execute("DELETE FROM {forumng_ratings}\n            WHERE postid IN ({$postquery})", $postparams);
     $DB->execute("DELETE FROM {forumng_read_posts}\n                WHERE postid IN ({$postquery})", $postparams);
     // Delete per-discussion data
     $discussionquery = "SELECT id FROM {forumng_discussions}\n            WHERE forumngid = ?";
     $discussionparams = array($this->forumfields->id);
     $DB->execute("DELETE FROM {forumng_read}\n            WHERE discussionid IN ({$discussionquery})", $discussionparams);
     $DB->execute("DELETE FROM {forumng_posts}\n            WHERE discussionid IN ({$discussionquery})", $discussionparams);
     // Delete standard rating data.
     if ($this->get_enableratings() == mod_forumng::FORUMNG_STANDARD_RATING && !$this->is_clone()) {
         require_once $CFG->dirroot . '/rating/lib.php';
         $delopt = new stdClass();
         $delopt->contextid = $this->get_context(true)->id;
         $delopt->component = 'mod_forumng';
         $delopt->ratingarea = 'post';
         $rm = new rating_manager();
         $rm->delete_ratings($delopt);
     }
     // Delete per-forum data
     if ($this->is_clone()) {
         $DB->delete_records('forumng_subscriptions', array('clonecmid' => $this->get_course_module_id()));
     } else {
         $DB->delete_records('forumng_subscriptions', array('forumngid' => $this->forumfields->id));
     }
     $DB->delete_records('forumng_discussions', array('forumngid' => $this->forumfields->id));
     // Delete tag instances.
     tag_delete_instances('mod_forumng', $this->context->id);
 }