예제 #1
0
function restore_create_metacourse($restore, $xml_file)
{
    global $CFG, $db;
    $status = true;
    //Check it exists
    if (!file_exists($xml_file)) {
        $status = false;
    }
    //Get info from xml
    if ($status) {
        //Load data from XML to info
        $info = restore_read_xml_metacourse($xml_file);
    }
    //Process info about metacourse
    if ($status and $info) {
        //Process child records
        if (!empty($info->childs)) {
            foreach ($info->childs as $child) {
                $dbcourse = false;
                $dbmetacourse = false;
                //Check if child course exists in destination server
                //(by id in the same server or by idnumber and shortname in other server)
                if (backup_is_same_site($restore)) {
                    //Same server, lets see by id
                    $dbcourse = get_record('course', 'id', $child->id);
                } else {
                    //Different server, lets see by idnumber and shortname, and only ONE record
                    $dbcount = count_records('course', 'idnumber', $child->idnumber, 'shortname', $child->shortname);
                    if ($dbcount == 1) {
                        $dbcourse = get_record('course', 'idnumber', $child->idnumber, 'shortname', $child->shortname);
                    }
                }
                //If child course has been found, insert data
                if ($dbcourse) {
                    $dbmetacourse->child_course = $dbcourse->id;
                    $dbmetacourse->parent_course = $restore->course_id;
                    $status = insert_record('course_meta', $dbmetacourse);
                } else {
                    //Child course not found, notice!
                    if (!defined('RESTORE_SILENTLY')) {
                        echo '<ul><li>' . get_string('childcoursenotfound') . ' (' . $child->id . '/' . $child->idnumber . '/' . $child->shortname . ')</li></ul>';
                    }
                }
            }
            //Now, recreate student enrolments...
            sync_metacourse($restore->course_id);
        }
        //Process parent records
        if (!empty($info->parents)) {
            foreach ($info->parents as $parent) {
                $dbcourse = false;
                $dbmetacourse = false;
                //Check if parent course exists in destination server
                //(by id in the same server or by idnumber and shortname in other server)
                if (backup_is_same_site($restore)) {
                    //Same server, lets see by id
                    $dbcourse = get_record('course', 'id', $parent->id);
                } else {
                    //Different server, lets see by idnumber and shortname, and only ONE record
                    $dbcount = count_records('course', 'idnumber', $parent->idnumber, 'shortname', $parent->shortname);
                    if ($dbcount == 1) {
                        $dbcourse = get_record('course', 'idnumber', $parent->idnumber, 'shortname', $parent->shortname);
                    }
                }
                //If parent course has been found, insert data if it is a metacourse
                if ($dbcourse) {
                    if ($dbcourse->metacourse) {
                        $dbmetacourse->parent_course = $dbcourse->id;
                        $dbmetacourse->child_course = $restore->course_id;
                        $status = insert_record('course_meta', $dbmetacourse);
                        //Now, recreate student enrolments in parent course
                        sync_metacourse($dbcourse->id);
                    } else {
                        //Parent course isn't metacourse, notice!
                        if (!defined('RESTORE_SILENTLY')) {
                            echo '<ul><li>' . get_string('parentcoursenotmetacourse') . ' (' . $parent->id . '/' . $parent->idnumber . '/' . $parent->shortname . ')</li></ul>';
                        }
                    }
                } else {
                    //Parent course not found, notice!
                    if (!defined('RESTORE_SILENTLY')) {
                        echo '<ul><li>' . get_string('parentcoursenotfound') . ' (' . $parent->id . '/' . $parent->idnumber . '/' . $parent->shortname . ')</li></ul>';
                    }
                }
            }
        }
    }
    return $status;
}
예제 #2
0
        }
        $msg .= '</p>';
        print_simple_box_start('center');
        notify($msg);
        print_simple_box_end();
    }
    //Back to Assign Roles button
    echo "<br/>";
    echo "<div class='continuebutton'>";
    print_single_button('assign.php', array('contextid' => $contextid), get_string('assignrolesin', 'role', print_context_name($context)));
    echo "</div>";
} else {
    // Print overview table
    // sync metacourse enrolments if needed
    if ($inmeta) {
        sync_metacourse($course);
    }
    // Get the names of role holders for roles with between 1 and MAX_USERS_TO_LIST_PER_ROLE users,
    // and so determine whether to show the extra column.
    $rolehodlercount = array();
    $rolehodlernames = array();
    $strmorethanten = get_string('morethan', 'role', MAX_USERS_TO_LIST_PER_ROLE);
    $showroleholders = false;
    foreach ($assignableroles as $roleid => $rolename) {
        $countusers = count_role_users($roleid, $context);
        $rolehodlercount[$roleid] = $countusers;
        $roleusers = '';
        if (0 < $countusers && $countusers <= MAX_USERS_TO_LIST_PER_ROLE) {
            $roleusers = get_role_users($roleid, $context, false, 'u.id, u.lastname, u.firstname');
            if (!empty($roleusers)) {
                $strroleusers = array();
예제 #3
0
/**
 * Clear a course out completely, deleting all content
 * but don't delete the course itself
 *
 * @uses $CFG
 * @param int $courseid The id of the course that is being deleted
 * @param bool $showfeedback Whether to display notifications of each action the function performs.
 * @return bool true if all the removals succeeded. false if there were any failures. If this
 *             method returns false, some of the removals will probably have succeeded, and others
 *             failed, but you have no way of knowing which.
 */
function remove_course_contents($courseid, $showfeedback = true)
{
    global $CFG;
    require_once $CFG->libdir . '/questionlib.php';
    require_once $CFG->libdir . '/gradelib.php';
    $result = true;
    if (!($course = get_record('course', 'id', $courseid))) {
        error('Course ID was incorrect (can\'t find it)');
    }
    $strdeleted = get_string('deleted');
    /// Clean up course formats (iterate through all formats in the even the course format was ever changed)
    $formats = get_list_of_plugins('course/format');
    foreach ($formats as $format) {
        $formatdelete = $format . '_course_format_delete_course';
        $formatlib = "{$CFG->dirroot}/course/format/{$format}/lib.php";
        if (file_exists($formatlib)) {
            include_once $formatlib;
            if (function_exists($formatdelete)) {
                if ($showfeedback) {
                    notify($strdeleted . ' ' . $format);
                }
                $formatdelete($course->id);
            }
        }
    }
    /// Delete every instance of every module
    if ($allmods = get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddelete = $modname . '_delete_instance';
            // Delete everything connected to an instance
            $moddeletecourse = $modname . '_delete_course';
            // Delete other stray stuff (uncommon)
            $count = 0;
            if (file_exists($modfile)) {
                include_once $modfile;
                if (function_exists($moddelete)) {
                    if ($instances = get_records($modname, 'course', $course->id)) {
                        foreach ($instances as $instance) {
                            if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) {
                                /// Delete activity context questions and question categories
                                question_delete_activity($cm, $showfeedback);
                            }
                            if ($moddelete($instance->id)) {
                                $count++;
                            } else {
                                notify('Could not delete ' . $modname . ' instance ' . $instance->id . ' (' . format_string($instance->name) . ')');
                                $result = false;
                            }
                            if ($cm) {
                                // delete cm and its context in correct order
                                delete_records('course_modules', 'id', $cm->id);
                                delete_context(CONTEXT_MODULE, $cm->id);
                            }
                        }
                    }
                } else {
                    notify('Function ' . $moddelete . '() doesn\'t exist!');
                    $result = false;
                }
                if (function_exists($moddeletecourse)) {
                    $moddeletecourse($course, $showfeedback);
                }
            }
            if ($showfeedback) {
                notify($strdeleted . ' ' . $count . ' x ' . $modname);
            }
        }
    } else {
        error('No modules are installed!');
    }
    /// Give local code a chance to delete its references to this course.
    require_once $CFG->libdir . '/locallib.php';
    notify_local_delete_course($courseid, $showfeedback);
    /// Delete course blocks
    if ($blocks = get_records_sql("SELECT *\n                                   FROM {$CFG->prefix}block_instance\n                                   WHERE pagetype = '" . PAGE_COURSE_VIEW . "'\n                                   AND pageid = {$course->id}")) {
        if (delete_records('block_instance', 'pagetype', PAGE_COURSE_VIEW, 'pageid', $course->id)) {
            if ($showfeedback) {
                notify($strdeleted . ' block_instance');
            }
            require_once $CFG->libdir . '/blocklib.php';
            foreach ($blocks as $block) {
                /// Delete any associated contexts for this block
                delete_context(CONTEXT_BLOCK, $block->id);
                // fix for MDL-7164
                // Get the block object and call instance_delete()
                if (!($record = blocks_get_record($block->blockid))) {
                    $result = false;
                    continue;
                }
                if (!($obj = block_instance($record->name, $block))) {
                    $result = false;
                    continue;
                }
                // Return value ignored, in core mods this does not do anything, but just in case
                // third party blocks might have stuff to clean up
                // we execute this anyway
                $obj->instance_delete();
            }
        } else {
            $result = false;
        }
    }
    /// Delete any groups, removing members and grouping/course links first.
    require_once $CFG->dirroot . '/group/lib.php';
    groups_delete_groupings($courseid, $showfeedback);
    groups_delete_groups($courseid, $showfeedback);
    /// Delete all related records in other tables that may have a courseid
    /// This array stores the tables that need to be cleared, as
    /// table_name => column_name that contains the course id.
    $tablestoclear = array('event' => 'courseid', 'log' => 'course', 'course_sections' => 'course', 'course_modules' => 'course', 'backup_courses' => 'courseid', 'user_lastaccess' => 'courseid', 'backup_log' => 'courseid');
    foreach ($tablestoclear as $table => $col) {
        if (delete_records($table, $col, $course->id)) {
            if ($showfeedback) {
                notify($strdeleted . ' ' . $table);
            }
        } else {
            $result = false;
        }
    }
    /// Clean up metacourse stuff
    if ($course->metacourse) {
        delete_records("course_meta", "parent_course", $course->id);
        sync_metacourse($course->id);
        // have to do it here so the enrolments get nuked. sync_metacourses won't find it without the id.
        if ($showfeedback) {
            notify("{$strdeleted} course_meta");
        }
    } else {
        if ($parents = get_records("course_meta", "child_course", $course->id)) {
            foreach ($parents as $parent) {
                remove_from_metacourse($parent->parent_course, $parent->child_course);
                // this will do the unenrolments as well.
            }
            if ($showfeedback) {
                notify("{$strdeleted} course_meta");
            }
        }
    }
    /// Delete questions and question categories
    question_delete_course($course, $showfeedback);
    /// Remove all data from gradebook
    $context = get_context_instance(CONTEXT_COURSE, $courseid);
    remove_course_grades($courseid, $showfeedback);
    remove_grade_letters($context, $showfeedback);
    return $result;
}
예제 #4
0
/**
 * Deletes one or more role assignments.   You must specify at least one parameter.
 * @param $roleid
 * @param $userid
 * @param $groupid
 * @param $contextid
 * @param $enrol unassign only if enrolment type matches, NULL means anything
 * @return boolean - success or failure
 */
function role_unassign($roleid = 0, $userid = 0, $groupid = 0, $contextid = 0, $enrol = NULL)
{
    global $USER, $CFG, $DB;
    require_once $CFG->dirroot . '/group/lib.php';
    $success = true;
    $args = array('roleid', 'userid', 'groupid', 'contextid');
    $select = array();
    $params = array();
    foreach ($args as $arg) {
        if (${$arg}) {
            $select[] = "{$arg} = ?";
            $params[] = ${$arg};
        }
    }
    if (!empty($enrol)) {
        $select[] = "enrol=?";
        $params[] = $enrol;
    }
    if ($select) {
        if ($ras = $DB->get_records_select('role_assignments', implode(' AND ', $select), $params)) {
            $mods = get_list_of_plugins('mod');
            foreach ($ras as $ra) {
                $fireevent = false;
                /// infinite loop protection when deleting recursively
                if (!($ra = $DB->get_record('role_assignments', array('id' => $ra->id)))) {
                    continue;
                }
                if ($DB->delete_records('role_assignments', array('id' => $ra->id))) {
                    $fireevent = true;
                } else {
                    $success = false;
                }
                if (!($context = get_context_instance_by_id($ra->contextid))) {
                    // strange error, not much to do
                    continue;
                }
                /* mark contexts as dirty here, because we need the refreshed
                 * caps bellow to delete group membership and user_lastaccess!
                 * and yes, this is very expensive for bulk operations :-(
                 */
                mark_context_dirty($context->path);
                /// If the user is the current user, then do full reload of capabilities too.
                if (!empty($USER->id) && $USER->id == $ra->userid) {
                    load_all_capabilities();
                }
                /// Ask all the modules if anything needs to be done for this user
                foreach ($mods as $mod) {
                    include_once $CFG->dirroot . '/mod/' . $mod . '/lib.php';
                    $functionname = $mod . '_role_unassign';
                    if (function_exists($functionname)) {
                        $functionname($ra->userid, $context);
                        // watch out, $context might be NULL if something goes wrong
                    }
                }
                /// now handle metacourse role unassigment and removing from goups if in course context
                if ($context->contextlevel == CONTEXT_COURSE) {
                    // cleanup leftover course groups/subscriptions etc when user has
                    // no capability to view course
                    // this may be slow, but this is the proper way of doing it
                    if (!has_capability('moodle/course:view', $context, $ra->userid)) {
                        // remove from groups
                        groups_delete_group_members($context->instanceid, $ra->userid);
                        // delete lastaccess records
                        $DB->delete_records('user_lastaccess', array('userid' => $ra->userid, 'courseid' => $context->instanceid));
                    }
                    //unassign roles in metacourses if needed
                    if ($parents = $DB->get_records('course_meta', array('child_course' => $context->instanceid))) {
                        foreach ($parents as $parent) {
                            sync_metacourse($parent->parent_course);
                        }
                    }
                }
                if ($fireevent) {
                    events_trigger('role_unassigned', $ra);
                }
            }
        }
    }
    return $success;
}
예제 #5
0
/**
 * Clear a course out completely, deleting all content
 * but don't delete the course itself
 *
 * @global object
 * @global object
 * @param int $courseid The id of the course that is being deleted
 * @param bool $showfeedback Whether to display notifications of each action the function performs.
 * @return bool true if all the removals succeeded. false if there were any failures. If this
 *             method returns false, some of the removals will probably have succeeded, and others
 *             failed, but you have no way of knowing which.
 */
function remove_course_contents($courseid, $showfeedback = true)
{
    global $CFG, $DB, $OUTPUT;
    require_once $CFG->libdir . '/questionlib.php';
    require_once $CFG->libdir . '/gradelib.php';
    $result = true;
    if (!($course = $DB->get_record('course', array('id' => $courseid)))) {
        print_error('invalidcourseid');
    }
    $context = get_context_instance(CONTEXT_COURSE, $courseid);
    $strdeleted = get_string('deleted');
    /// Clean up course formats (iterate through all formats in the even the course format was ever changed)
    $formats = get_plugin_list('format');
    foreach ($formats as $format => $formatdir) {
        $formatdelete = $format . '_course_format_delete_course';
        $formatlib = "{$formatdir}/lib.php";
        if (file_exists($formatlib)) {
            include_once $formatlib;
            if (function_exists($formatdelete)) {
                if ($showfeedback) {
                    echo $OUTPUT->notification($strdeleted . ' ' . $format);
                }
                $formatdelete($course->id);
            }
        }
    }
    /// Delete every instance of every module
    if ($allmods = $DB->get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddelete = $modname . '_delete_instance';
            // Delete everything connected to an instance
            $moddeletecourse = $modname . '_delete_course';
            // Delete other stray stuff (uncommon)
            $count = 0;
            if (file_exists($modfile)) {
                include_once $modfile;
                if (function_exists($moddelete)) {
                    if ($instances = $DB->get_records($modname, array('course' => $course->id))) {
                        foreach ($instances as $instance) {
                            if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) {
                                /// Delete activity context questions and question categories
                                question_delete_activity($cm, $showfeedback);
                            }
                            if ($moddelete($instance->id)) {
                                $count++;
                            } else {
                                echo $OUTPUT->notification('Could not delete ' . $modname . ' instance ' . $instance->id . ' (' . format_string($instance->name) . ')');
                                $result = false;
                            }
                            if ($cm) {
                                // delete cm and its context in correct order
                                $DB->delete_records('course_modules', array('id' => $cm->id));
                                delete_context(CONTEXT_MODULE, $cm->id);
                            }
                        }
                    }
                } else {
                    echo $OUTPUT->notification('Function ' . $moddelete . '() doesn\'t exist!');
                    $result = false;
                }
                if (function_exists($moddeletecourse)) {
                    $moddeletecourse($course, $showfeedback);
                }
            }
            if ($showfeedback) {
                echo $OUTPUT->notification($strdeleted . ' ' . $count . ' x ' . $modname);
            }
        }
    } else {
        print_error('nomodules', 'debug');
    }
    /// Delete course blocks
    blocks_delete_all_for_context($context->id);
    /// Delete any groups, removing members and grouping/course links first.
    require_once $CFG->dirroot . '/group/lib.php';
    groups_delete_groupings($courseid, $showfeedback);
    groups_delete_groups($courseid, $showfeedback);
    /// Delete all related records in other tables that may have a courseid
    /// This array stores the tables that need to be cleared, as
    /// table_name => column_name that contains the course id.
    $tablestoclear = array('event' => 'courseid', 'log' => 'course', 'course_sections' => 'course', 'course_modules' => 'course', 'backup_courses' => 'courseid', 'user_lastaccess' => 'courseid', 'backup_log' => 'courseid');
    foreach ($tablestoclear as $table => $col) {
        if ($DB->delete_records($table, array($col => $course->id))) {
            if ($showfeedback) {
                echo $OUTPUT->notification($strdeleted . ' ' . $table);
            }
        } else {
            $result = false;
        }
    }
    /// Clean up metacourse stuff
    if ($course->metacourse) {
        $DB->delete_records("course_meta", array("parent_course" => $course->id));
        sync_metacourse($course->id);
        // have to do it here so the enrolments get nuked. sync_metacourses won't find it without the id.
        if ($showfeedback) {
            echo $OUTPUT->notification("{$strdeleted} course_meta");
        }
    } else {
        if ($parents = $DB->get_records("course_meta", array("child_course" => $course->id))) {
            foreach ($parents as $parent) {
                remove_from_metacourse($parent->parent_course, $parent->child_course);
                // this will do the unenrolments as well.
            }
            if ($showfeedback) {
                echo $OUTPUT->notification("{$strdeleted} course_meta");
            }
        }
    }
    /// Delete questions and question categories
    question_delete_course($course, $showfeedback);
    /// Remove all data from gradebook
    remove_course_grades($courseid, $showfeedback);
    remove_grade_letters($context, $showfeedback);
    /// Delete course tags
    require_once $CFG->dirroot . '/tag/coursetagslib.php';
    coursetag_delete_course_tags($course->id, $showfeedback);
    return $result;
}
예제 #6
0
/**
 * Deletes one or more role assignments.   You must specify at least one parameter.
 * @param $roleid
 * @param $userid
 * @param $groupid
 * @param $contextid
 * @param $enrol unassign only if enrolment type matches, NULL means anything
 * @return boolean - success or failure
 */
function role_unassign($roleid = 0, $userid = 0, $groupid = 0, $contextid = 0, $enrol = NULL)
{
    global $USER, $CFG;
    $success = true;
    $args = array('roleid', 'userid', 'groupid', 'contextid');
    $select = array();
    foreach ($args as $arg) {
        if (${$arg}) {
            $select[] = $arg . ' = ' . ${$arg};
        }
    }
    if (!empty($enrol)) {
        $select[] = "enrol='{$enrol}'";
    }
    if ($select) {
        if ($ras = get_records_select('role_assignments', implode(' AND ', $select))) {
            $mods = get_list_of_plugins('mod');
            foreach ($ras as $ra) {
                /// infinite loop protection when deleting recursively
                if (!($ra = get_record('role_assignments', 'id', $ra->id))) {
                    continue;
                }
                $success = delete_records('role_assignments', 'id', $ra->id) and $success;
                /// If the user is the current user, then reload the capabilities too.
                if (!empty($USER->id) && $USER->id == $ra->userid) {
                    load_all_capabilities();
                }
                $context = get_record('context', 'id', $ra->contextid);
                /// Ask all the modules if anything needs to be done for this user
                foreach ($mods as $mod) {
                    include_once $CFG->dirroot . '/mod/' . $mod . '/lib.php';
                    $functionname = $mod . '_role_unassign';
                    if (function_exists($functionname)) {
                        $functionname($ra->userid, $context);
                        // watch out, $context might be NULL if something goes wrong
                    }
                }
                /// now handle metacourse role unassigment and removing from goups if in course context
                if (!empty($context) and $context->contextlevel == CONTEXT_COURSE) {
                    // cleanup leftover course groups/subscriptions etc when user has
                    // no capability to view course
                    // this may be slow, but this is the proper way of doing it
                    if (!has_capability('moodle/course:view', $context, $ra->userid)) {
                        // remove from groups
                        if ($groups = groups_get_all_groups($context->instanceid)) {
                            foreach ($groups as $group) {
                                delete_records('groups_members', 'groupid', $group->id, 'userid', $ra->userid);
                            }
                        }
                        // delete lastaccess records
                        delete_records('user_lastaccess', 'userid', $ra->userid, 'courseid', $context->instanceid);
                    }
                    //unassign roles in metacourses if needed
                    if ($parents = get_records('course_meta', 'child_course', $context->instanceid)) {
                        foreach ($parents as $parent) {
                            sync_metacourse($parent->parent_course);
                        }
                    }
                }
            }
        }
    }
    return $success;
}
예제 #7
0
/**
 * Clear a course out completely, deleting all content
 * but don't delete the course itself
 *
 * @uses $CFG
 * @param int $courseid The id of the course that is being deleted
 * @param bool $showfeedback Whether to display notifications of each action the function performs.
 * @return bool true if all the removals succeeded. false if there were any failures. If this
 *             method returns false, some of the removals will probably have succeeded, and others
 *             failed, but you have no way of knowing which.
 */
function remove_course_contents($courseid, $showfeedback = true)
{
    global $CFG;
    $result = true;
    if (!($course = get_record('course', 'id', $courseid))) {
        error('Course ID was incorrect (can\'t find it)');
    }
    $strdeleted = get_string('deleted');
    /// First delete every instance of every module
    if ($allmods = get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            $modfile = $CFG->dirroot . '/mod/' . $modname . '/lib.php';
            $moddelete = $modname . '_delete_instance';
            // Delete everything connected to an instance
            $moddeletecourse = $modname . '_delete_course';
            // Delete other stray stuff (uncommon)
            $count = 0;
            if (file_exists($modfile)) {
                include_once $modfile;
                if (function_exists($moddelete)) {
                    if ($instances = get_records($modname, 'course', $course->id)) {
                        foreach ($instances as $instance) {
                            if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) {
                                delete_context(CONTEXT_MODULE, $cm->id);
                            }
                            if ($moddelete($instance->id)) {
                                $count++;
                            } else {
                                notify('Could not delete ' . $modname . ' instance ' . $instance->id . ' (' . format_string($instance->name) . ')');
                                $result = false;
                            }
                        }
                    }
                } else {
                    notify('Function ' . $moddelete . '() doesn\'t exist!');
                    $result = false;
                }
                if (function_exists($moddeletecourse)) {
                    $moddeletecourse($course, $showfeedback);
                }
            }
            if ($showfeedback) {
                notify($strdeleted . ' ' . $count . ' x ' . $modname);
            }
        }
    } else {
        error('No modules are installed!');
    }
    /// Give local code a chance to delete its references to this course.
    require_once 'locallib.php';
    notify_local_delete_course($courseid, $showfeedback);
    /// Delete course blocks
    if ($blocks = get_records_sql("SELECT *\n                                   FROM {$CFG->prefix}block_instance\n                                   WHERE pagetype = '" . PAGE_COURSE_VIEW . "'\n                                   AND pageid = {$course->id}")) {
        if (delete_records('block_instance', 'pagetype', PAGE_COURSE_VIEW, 'pageid', $course->id)) {
            if ($showfeedback) {
                notify($strdeleted . ' block_instance');
            }
            require_once $CFG->libdir . '/blocklib.php';
            foreach ($blocks as $block) {
                /// Delete any associated contexts for this block
                // Block instances are rarely created. Since the block instance is gone from the above delete
                // statement, calling delete_context() will generate a warning as get_context_instance could
                // no longer create the context as the block is already gone.
                if (record_exists('context', 'contextlevel', CONTEXT_BLOCK, 'instanceid', $block->id)) {
                    delete_context(CONTEXT_BLOCK, $block->id);
                }
                // fix for MDL-7164
                // Get the block object and call instance_delete()
                if (!($record = blocks_get_record($block->blockid))) {
                    $result = false;
                    continue;
                }
                if (!($obj = block_instance($record->name, $block))) {
                    $result = false;
                    continue;
                }
                // Return value ignored, in core mods this does not do anything, but just in case
                // third party blocks might have stuff to clean up
                // we execute this anyway
                $obj->instance_delete();
            }
        } else {
            $result = false;
        }
    }
    /// Delete any groups, removing members and grouping/course links first.
    //TODO: If groups or groupings are to be shared between courses, think again!
    if ($groupids = groups_get_groups($course->id)) {
        foreach ($groupids as $groupid) {
            if (groups_remove_all_members($groupid)) {
                if ($showfeedback) {
                    notify($strdeleted . ' groups_members');
                }
            } else {
                $result = false;
            }
            /// Delete any associated context for this group ??
            delete_context(CONTEXT_GROUP, $groupid);
            if (groups_delete_group($groupid)) {
                if ($showfeedback) {
                    notify($strdeleted . ' groups');
                }
            } else {
                $result = false;
            }
        }
    }
    /// Delete any groupings.
    $result = groups_delete_all_groupings($course->id);
    if ($result && $showfeedback) {
        notify($strdeleted . ' groupings');
    }
    /// Delete all related records in other tables that may have a courseid
    /// This array stores the tables that need to be cleared, as
    /// table_name => column_name that contains the course id.
    $tablestoclear = array('event' => 'courseid', 'log' => 'course', 'course_sections' => 'course', 'course_modules' => 'course', 'grade_category' => 'courseid', 'grade_exceptions' => 'courseid', 'grade_item' => 'courseid', 'grade_letter' => 'courseid', 'grade_preferences' => 'courseid', 'backup_courses' => 'courseid', 'backup_log' => 'courseid');
    foreach ($tablestoclear as $table => $col) {
        if (delete_records($table, $col, $course->id)) {
            if ($showfeedback) {
                notify($strdeleted . ' ' . $table);
            }
        } else {
            $result = false;
        }
    }
    /// Clean up metacourse stuff
    if ($course->metacourse) {
        delete_records("course_meta", "parent_course", $course->id);
        sync_metacourse($course->id);
        // have to do it here so the enrolments get nuked. sync_metacourses won't find it without the id.
        if ($showfeedback) {
            notify("{$strdeleted} course_meta");
        }
    } else {
        if ($parents = get_records("course_meta", "child_course", $course->id)) {
            foreach ($parents as $parent) {
                remove_from_metacourse($parent->parent_course, $parent->child_course);
                // this will do the unenrolments as well.
            }
            if ($showfeedback) {
                notify("{$strdeleted} course_meta");
            }
        }
    }
    /// Delete questions and question categories
    include_once $CFG->libdir . '/questionlib.php';
    question_delete_course($course, $showfeedback);
    /// Delete all roles and overiddes in the course context (but keep the course context)
    if ($courseid != SITEID) {
        delete_context(CONTEXT_COURSE, $course->id);
    }
    // fix for MDL-9016
    // clear the cache because the course context is deleted, and
    // we don't want to write assignment, overrides and context_rel table
    // with this old context id!
    get_context_instance('clearcache');
    return $result;
}