예제 #1
0
 public function execute()
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/course/lib.php';
     $moduleid = intval($this->arguments[0]);
     if ($moduleid <= 0) {
         cli_error("Argument 'moduleid' must be bigger than 0.");
     }
     if (!$DB->get_record('course_modules', array('id' => $this->arguments[0]))) {
         cli_error("There is no such activity to delete.");
     }
     course_delete_module($moduleid);
     echo "Deleted activity {$moduleid}\n";
 }
 /**
  * Resets (truncates) all dataform tables to remove any records and reset sequences.
  * This set of steps is essential for any standalone scenario that adds entries with content
  * since such a scenario has to refer to input elements by the name field_{fieldid}_{entryid}
  * (or field_{fieldid}_-1 for a new entry) and the ids have to persist between runs.
  *
  * @Given /^a fresh site for dataform scenario$/
  * @return array
  */
 public function start_afresh_steps()
 {
     global $DB;
     // Dataform module id.
     $moduleid = $DB->get_field('modules', 'id', array('name' => 'dataform'));
     // CM ids.
     if ($cmids = $DB->get_records('course_modules', array('module' => $moduleid), '', 'id,id AS cmid')) {
         // Delete properly any existing dataform instances.
         foreach ($cmids as $cmid) {
             course_delete_module($cmid);
         }
     }
     // Clean up tables.
     $tables = array('dataform', 'dataform_contents', 'dataform_entries', 'dataform_fields', 'dataform_filters', 'dataform_views');
     $prefix = $DB->get_prefix();
     foreach ($tables as $table) {
         $DB->execute("TRUNCATE TABLE {$prefix}{$table}");
     }
     // Clean up instance store cache.
     \mod_dataform_instance_store::unregister();
     $steps = array();
     // Add a course.
     $data = array('| fullname | shortname | category  |', '| Course 1 | C1        | 0         |');
     $table = new TableNode(implode("\n", $data));
     $steps[] = new Given('the following "courses" exist:', $table);
     // Add users.
     $data = array('| username     | firstname | lastname  | email                 |', '| teacher1     | Teacher   | 1         | teacher1@asd.com      |', '| assistant1   | Assistant | 1         | assistant1@asd.com    |', '| assistant2   | Assistant | 2         | assistant2@asd.com    |', '| student1     | Student   | 1         | student1@asd.com      |', '| student2     | Student   | 2         | student2@asd.com      |', '| student3     | Student   | 3         | student3@asd.com      |');
     $table = new TableNode(implode("\n", $data));
     $steps[] = new Given('the following "users" exist:', $table);
     // Enrol users in course.
     $teacherrole = \mod_dataform\helper\testing::get_role_shortname('editingteacher');
     $assistantrole = \mod_dataform\helper\testing::get_role_shortname('teacher');
     $studentrole = \mod_dataform\helper\testing::get_role_shortname('student');
     $data = array('| user         | course | role             |', "| teacher1     | C1     | {$teacherrole}     |", "| assistant1   | C1     | {$assistantrole}   |", "| assistant2   | C1     | {$assistantrole}   |", "| student1     | C1     | {$studentrole}     |", "| student2     | C1     | {$studentrole}     |");
     $table = new TableNode(implode("\n", $data));
     $steps[] = new Given('the following "course enrolments" exist:', $table);
     // Add groups.
     $data = array('| name    | description | course  | idnumber |', '| Group 1 | Anything    | C1 | G1   |', '| Group 2 | Anything    | C1 | G2   |');
     $table = new TableNode(implode("\n", $data));
     $steps[] = new Given('the following "groups" exist:', $table);
     // Add group members.
     $data = array('| user     | group  |', '| student1 | G1 |', '| student2 | G2 |');
     $table = new TableNode(implode("\n", $data));
     $steps[] = new Given('the following "group members" exist:', $table);
     return $steps;
 }
예제 #3
0
 /**
  * Run the deletion task.
  *
  * @throws \coding_exception if the module could not be removed.
  */
 public function execute()
 {
     global $CFG;
     require_once $CFG->dirroot . '/course/lib.php';
     // Set the proper user.
     if ($this->get_custom_data()->userid !== $this->get_custom_data()->realuserid) {
         $realuser = \core_user::get_user($this->get_custom_data()->realuserid, '*', MUST_EXIST);
         cron_setup_user($realuser);
         \core\session\manager::loginas($this->get_custom_data()->userid, \context_system::instance(), false);
     } else {
         $user = \core_user::get_user($this->get_custom_data()->userid, '*', MUST_EXIST);
         cron_setup_user($user);
     }
     $cms = $this->get_custom_data()->cms;
     foreach ($cms as $cm) {
         try {
             course_delete_module($cm->id);
         } catch (\Exception $e) {
             throw new \coding_exception("The course module {$cm->id} could not be deleted. {$e->getTraceAsString()}");
         }
     }
 }
 /**
  * Tests the event details.
  */
 public function test_event()
 {
     global $CFG;
     require_once "{$CFG->libdir}/gradelib.php";
     $this->resetAfterTest();
     $course = $this->getDataGenerator()->create_course();
     $user = $this->getDataGenerator()->create_user();
     $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
     // Create a grade item for the quiz.
     $grade = array();
     $grade['userid'] = $user->id;
     $grade['rawgrade'] = 50;
     grade_update('mod/quiz', $course->id, 'mod', 'quiz', $quiz->id, 0, $grade);
     // Get the grade item and override it.
     $gradeitem = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'courseid' => $course->id));
     $gradeitem->update_final_grade($user->id, 10, 'gradebook');
     // Get the grade_grade object.
     $gradegrade = new grade_grade(array('userid' => $user->id, 'itemid' => $gradeitem->id), true);
     $gradegrade->grade_item = $gradeitem;
     // Trigger the event.
     $sink = $this->redirectEvents();
     course_delete_module($quiz->cmid);
     $events = $sink->get_events();
     $event = reset($events);
     $sink->close();
     // Check the event details are correct.
     $grade = $event->get_grade();
     $this->assertInstanceOf('grade_grade', $grade);
     $this->assertInstanceOf('\\core\\event\\grade_deleted', $event);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     $this->assertSame($event->objecttable, 'grade_grades');
     $this->assertEquals($event->objectid, $gradegrade->id);
     $this->assertEquals($event->other['itemid'], $gradeitem->id);
     $this->assertTrue($event->other['overridden']);
     $this->assertEquals(10, $event->other['finalgrade']);
     $this->assertEventContextNotUsed($event);
     $this->assertEquals($gradegrade->id, $grade->id);
 }
예제 #5
0
                        // Attempt to update the grade item if relevant
                        $grademodule = $DB->get_record($cm->modname, array('id' => $cm->instance));
                        $grademodule->cmidnumber = $cm->idnumber;
                        $grademodule->modname = $cm->modname;
                        grade_update_mod_grades($grademodule);
                        // We need to return strings after they've been through filters for multilang
                        $stringoptions = new stdClass();
                        $stringoptions->context = $coursecontext;
                        echo json_encode(array('instancename' => html_entity_decode(format_string($module->name, true, $stringoptions))));
                        break;
                }
                break;
            case 'course':
                switch ($field) {
                    case 'marker':
                        require_capability('moodle/course:setcurrentsection', $coursecontext);
                        course_set_marker($course->id, $value);
                        break;
                }
                break;
        }
        break;
    case 'DELETE':
        switch ($class) {
            case 'resource':
                require_capability('moodle/course:manageactivities', $modcontext);
                course_delete_module($cm->id);
                break;
        }
        break;
}
예제 #6
0
파일: lib.php 프로젝트: etarrillo/pvflbl
 /**
  * Completely removes a section, all subsections and activities they contain
  *
  * @param section_info $section
  */
 protected function delete_section_int($section)
 {
     global $DB;
     if (!$section->section) {
         // section 0 does not have parent
         return;
     }
     $sectionid = $section->id;
     // move the section to be removed to the end (this will re-number other sections)
     $this->move_section($section->section, 0);
     $modinfo = get_fast_modinfo($this->courseid);
     $allsections = $modinfo->get_section_info_all();
     $section = null;
     $sectionstodelete = array();
     $modulestodelete = array();
     foreach ($allsections as $sectioninfo) {
         if ($sectioninfo->id == $sectionid) {
             // This is the section to be deleted. Since we have already
             // moved it to the end we know that we need to delete this section
             // and all the following (which can only be its subsections).
             $section = $sectioninfo;
         }
         if ($section) {
             $sectionstodelete[] = $sectioninfo->id;
             if (!empty($modinfo->sections[$sectioninfo->section])) {
                 $modulestodelete = array_merge($modulestodelete, $modinfo->sections[$sectioninfo->section]);
             }
         }
     }
     foreach ($modulestodelete as $cmid) {
         course_delete_module($cmid);
     }
     list($sectionsql, $params) = $DB->get_in_or_equal($sectionstodelete);
     $DB->execute('DELETE FROM {course_format_options} WHERE sectionid ' . $sectionsql, $params);
     $DB->execute('DELETE FROM {course_sections} WHERE id ' . $sectionsql, $params);
     rebuild_course_cache($this->courseid, true);
 }
예제 #7
0
파일: rest.php 프로젝트: lucaboesch/moodle
                        }
                        if ($beforeid > 0) {
                            $beforemod = get_coursemodule_from_id('', $beforeid, $course->id);
                            $beforemod = $DB->get_record('course_modules', array('id' => $beforeid));
                        } else {
                            $beforemod = NULL;
                        }
                        $isvisible = moveto_module($cm, $section, $beforemod);
                        echo json_encode(array('visible' => (bool) $isvisible));
                        break;
                }
                break;
            case 'course':
                switch ($field) {
                    case 'marker':
                        require_capability('moodle/course:setcurrentsection', $coursecontext);
                        course_set_marker($course->id, $value);
                        break;
                }
                break;
        }
        break;
    case 'DELETE':
        switch ($class) {
            case 'resource':
                require_capability('moodle/course:manageactivities', $modcontext);
                course_delete_module($cm->id, true);
                break;
        }
        break;
}
예제 #8
0
    public function test_upgrade_offline_assignment() {
        global $DB;

        $this->setUser($this->editingteachers[0]);
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_assignment');
        $params = array('course'=>$this->course->id,
                        'assignmenttype'=>'offline');
        $record = $generator->create_instance($params);

        $assignment = new assignment_base($record->cmid);

        $this->setAdminUser();
        $log = '';
        $upgrader = new assign_upgrade_manager();

        $this->assertTrue($upgrader->upgrade_assignment($assignment->assignment->id, $log));
        $record = $DB->get_record('assign', array('course'=>$this->course->id));

        $cm = get_coursemodule_from_instance('assign', $record->id);
        $context = context_module::instance($cm->id);

        $assign = new assign($context, $cm, $this->course);

        $plugin = $assign->get_submission_plugin_by_type('onlinetext');
        $this->assertEmpty($plugin->is_enabled());
        $plugin = $assign->get_submission_plugin_by_type('comments');
        $this->assertEmpty($plugin->is_enabled());
        $plugin = $assign->get_submission_plugin_by_type('file');
        $this->assertEmpty($plugin->is_enabled());
        $plugin = $assign->get_feedback_plugin_by_type('comments');
        $this->assertNotEmpty($plugin->is_enabled());
        $plugin = $assign->get_feedback_plugin_by_type('file');
        $this->assertEmpty($plugin->is_enabled());
        $plugin = $assign->get_feedback_plugin_by_type('offline');
        $this->assertEmpty($plugin->is_enabled());

        course_delete_module($cm->id);
    }
예제 #9
0
 public static function delete_item($user, $itemid)
 {
     global $DB, $USER;
     $params = self::validate_parameters(self::delete_item_parameters(), array('user' => $user, 'itemid' => $itemid));
     $item = $DB->get_record('equella', array('id' => $params['itemid']), '*', MUST_EXIST);
     self::check_modify_permissions($params['user'], $item->course);
     $cm = get_coursemodule_from_instance('equella', $item->id, $item->course, false, MUST_EXIST);
     $success = true;
     try {
         course_delete_module($cm->id);
     } catch (Exception $ex) {
         $success = false;
         throw $ex;
     }
     return array('success' => $success);
 }
예제 #10
0
 /**
  * Called after the mod has set itself up, to finish off any course module settings
  * (set instance id, add to correct section, set visibility, etc.) and send the response
  *
  * @param int $instanceid id returned by the mod when it was created
  */
 protected function finish_setup_course_module($instanceid)
 {
     global $DB, $USER;
     if (!$instanceid) {
         // Something has gone wrong - undo everything we can.
         course_delete_module($this->cm->id);
         throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
     }
     // Note the section visibility
     $visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible;
     $DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id));
     // Rebuild the course cache after update action
     rebuild_course_cache($this->course->id, true);
     $sectionid = course_add_cm_to_section($this->course, $this->cm->id, $this->section);
     set_coursemodule_visible($this->cm->id, $visible);
     if (!$visible) {
         $DB->set_field('course_modules', 'visibleold', 1, array('id' => $this->cm->id));
     }
     // retrieve the final info about this module.
     $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.
         course_delete_module($this->cm->id);
         throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
     }
     $mod = $info->get_cm($this->cm->id);
     // Trigger course module created event.
     $event = \core\event\course_module_created::create(array('courseid' => $this->course->id, 'context' => context_module::instance($mod->id), 'objectid' => $mod->id, 'other' => array('modulename' => $mod->modname, 'name' => $mod->name, 'instanceid' => $instanceid)));
     $event->trigger();
     add_to_log($this->course->id, $mod->modname, "add", "view.php?id={$mod->id}", "{$instanceid}", $mod->id);
     $this->send_response($mod);
 }
예제 #11
0
function forumng_delete_instance($id)
{
    global $DB;
    require_once dirname(__FILE__) . '/mod_forumng.php';
    $cm = get_coursemodule_from_instance('forumng', $id);
    $forum = mod_forumng::get_from_id($id, mod_forumng::CLONE_DIRECT, true, $cm);
    $forum->delete_all_data();
    if (mod_forumng::search_installed()) {
        $cm = $forum->get_course_module();
        local_ousearch_document::delete_module_instance_data($cm);
    }
    if ($forum->is_shared()) {
        // Find all the clone instances.
        $clones = $forum->get_clone_details();
        $transaction = $DB->start_delegated_transaction();
        foreach ($clones as $clone) {
            try {
                course_delete_module($clone->context->instanceid);
            } catch (moodle_exception $e) {
                notify("Could not delete the Clone\n                        forumng (coursemoduleid) {$clone->context}->instanceid ");
                return false;
            }
            rebuild_course_cache($clone->courseid, true);
        }
        $transaction->allow_commit();
    }
    return $DB->delete_records('forumng', array('id' => $id));
}
예제 #12
0
 /**
  * function used to delete a module - copied from course/mod.php, it would
  * be nice for this to be a core function.
  * @param stdclass $cm full course modules record
  */
 public function delete_module($cm)
 {
     global $CFG, $OUTPUT, $USER, $DB;
     $cm->modname = $DB->get_field("modules", "name", array("id" => $cm->module));
     $modlib = "{$CFG->dirroot}/mod/{$cm->modname}/lib.php";
     if (file_exists($modlib)) {
         require_once $modlib;
     } else {
         print_error('modulemissingcode', '', '', $modlib);
     }
     try {
         course_delete_module($cm->id);
     } catch (moodle_exception $e) {
         echo $OUTPUT->notification("Could not delete the {$cm->modname} (coursemodule)");
     }
     rebuild_course_cache($cm->course);
 }
예제 #13
0
 }
 $params = array("module" => "{$cm->module}", "refid" => "{$val}");
 $sql = "SELECT * FROM {course_modules} WHERE module = :module AND instance=:refid ";
 $courses_modules = $DB->get_records_sql($sql, $params);
 if ($courses_modules) {
     foreach ($courses_modules as $course_module) {
         if (!empty($course_module)) {
             if ($course_record = $DB->get_record("course", array("id" => "{$course_module->course}"))) {
                 require_login($course_module->course);
                 // needed to setup proper $COURSE
                 $context_course = context_course::instance($course_module->course);
                 require_capability('moodle/course:manageactivities', $context_course);
                 if ($that_instance = $DB->get_record("referentiel", array("id" => "{$course_module->instance}"))) {
                     if (function_exists('course_delete_module')) {
                         // Moodle v 2.5 et suivantes
                         if (course_delete_module($course_module->id)) {
                             if (delete_mod_from_section($course_module->id, "{$course_module->section}")) {
                                 rebuild_course_cache($course_record->id);
                                 $msg .= get_string('instance_deleted', 'referentiel') . ' ' . $that_instance->name;
                             }
                         }
                     } else {
                         // Moodle v 2.x
                         if (delete_course_module($course_module->id)) {
                             if (delete_mod_from_section($course_module->id, "{$course_module->section}")) {
                                 rebuild_course_cache($course_record->id);
                                 $msg .= get_string('instance_deleted', 'referentiel') . ' ' . $that_instance->name;
                             }
                         }
                     }
                     // Supprimer l'instance
예제 #14
0
 /**
  * Test the course bin item restored event.
  */
 public function test_course_bin_item_restored()
 {
     // Create a course.
     $course = $this->getDataGenerator()->create_course();
     // Create the assignment.
     $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
     $instance = $generator->create_instance(array('course' => $course->id));
     course_delete_module($instance->cmid);
     // Get the item from the recycle bin.
     $rb = new \tool_recyclebin\course_bin($course->id);
     $items = $rb->get_items();
     $item = reset($items);
     // Trigger and capture the event.
     $sink = $this->redirectEvents();
     $rb->restore_item($item);
     $events = $sink->get_events();
     $event = reset($events);
     // Check that the event contains the expected values.
     $this->assertInstanceOf('\\tooL_recyclebin\\event\\course_bin_item_restored', $event);
     $this->assertEquals(context_course::instance($course->id), $event->get_context());
     $this->assertEquals($item->id, $event->objectid);
     $this->assertEventContextNotUsed($event);
 }
예제 #15
0
function pearsondirect_handle_code_change($courseconfig, $newcode, $newparams)
{
    global $DB, $CFG;
    require_once $CFG->dirroot . '/mod/lti/locallib.php';
    require_once $CFG->dirroot . '/course/lib.php';
    $types = $DB->get_records('lti_types', array('course' => $courseconfig->course));
    if ($types) {
        foreach ($types as $type) {
            if (!strncmp($type->tooldomain, 'pearson:', strlen('pearson:'))) {
                lti_delete_type($type->id);
            }
        }
    }
    $coursemodules = $DB->get_records('course_modules', array('course' => $courseconfig->course, 'module' => pearsondirect_get_lti_module()));
    if ($coursemodules) {
        foreach ($coursemodules as $cm) {
            if (!strncmp($cm->idnumber, 'pearson:', strlen('pearson:'))) {
                course_delete_module($cm->id);
            }
        }
    }
}
예제 #16
0
 /**
  * Test observer for course module delete event.
  */
 public function test_course_module_deleted()
 {
     global $DB;
     $this->setAdminUser();
     $this->resetAfterTest(true);
     $user = $this->getDataGenerator()->create_user();
     $course1 = $this->getDataGenerator()->create_course();
     $course2 = $this->getDataGenerator()->create_course();
     $monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
     // Now let us create a rule specific to a module instance.
     $cm = new stdClass();
     $cm->course = $course1->id;
     $book = $this->getDataGenerator()->create_module('book', $cm);
     $rule = new stdClass();
     $rule->userid = $user->id;
     $rule->courseid = $course1->id;
     $rule->plugin = 'test';
     $sub = new stdClass();
     $sub->courseid = $course1->id;
     $sub->userid = $user->id;
     $sub->cmid = $book->cmid;
     // Add 10 rules for this course with subscriptions for this module.
     for ($i = 0; $i < 10; $i++) {
         $createdrule = $monitorgenerator->create_rule($rule);
         $sub->ruleid = $createdrule->id;
         $monitorgenerator->create_subscription($sub);
     }
     // Add 10 random rules for course 2.
     $rule->courseid = $course2->id;
     for ($i = 0; $i < 10; $i++) {
         $createdrule = $monitorgenerator->create_rule($rule);
         $sub->courseid = $rule->courseid;
         $sub->ruleid = $createdrule->id;
         $sub->cmid = 0;
         $monitorgenerator->create_subscription($sub);
     }
     // Verify data before module delete.
     $totalrules = \tool_monitor\rule_manager::get_rules_by_plugin('test');
     $this->assertCount(20, $totalrules);
     $totalsubs = $DB->get_records('tool_monitor_subscriptions');
     $this->assertCount(20, $totalsubs);
     // Let us delete the user now.
     course_delete_module($book->cmid);
     // Verify data after course delete.
     $totalrules = \tool_monitor\rule_manager::get_rules_by_plugin('test');
     $this->assertCount(20, $totalrules);
     $totalsubs = $DB->get_records('tool_monitor_subscriptions');
     $this->assertCount(10, $totalsubs);
     // Make sure only relevant subscriptions are deleted.
 }
 /**
  * Delete activities, when course format setting "deletemodspermanently" is set
  * to yes and the activitie is not attached to another post.
  * 
  * @param int $pid, the id of the post.
  * @return boolean, true when at least one acitivity is deleted.
  */
 protected static function delete_posts_activities($pid)
 {
     global $DB, $CFG;
     require_once $CFG->dirroot . '/course/format/lib.php';
     // Get the course and check, whether the format is "socialwall".
     $sql = "SELECT c.* FROM {course} c\n                JOIN {format_socialwall_posts} p ON p.courseid = c.id\n                WHERE p.id = :pid AND c.format = 'socialwall'";
     if (!($course = $DB->get_record_sql($sql, array('pid' => $pid)))) {
         return false;
     }
     $course = course_get_format($course)->get_course();
     if (empty($course->deletemodspermanently)) {
         return false;
     }
     $sql = "SELECT a.coursemoduleid, count(*) as countmod\n                 FROM {format_socialwall_attaches} a\n                 JOIN {format_socialwall_posts} p ON (p.id = a.postid AND p.courseid = :courseid)\n                 JOIN {format_socialwall_attaches} a2 ON (a2.coursemoduleid = a.coursemoduleid AND a2.postid = :pid)\n                 GROUP BY coursemoduleid\n                 HAVING countmod = '1'";
     if (!($modcounts = $DB->get_records_sql($sql, array('courseid' => $course->id, 'pid' => $pid)))) {
         return false;
     }
     $cmids = array_keys($modcounts);
     foreach ($cmids as $cmid) {
         course_delete_module($cmid);
     }
     return true;
 }
예제 #18
0
/**
 * Given a course_module object, this function returns any
 * "extra" information that may be needed when printing
 * this activity in a course listing.
 * See get_array_of_activities() in course/lib.php
 */
function customlabel_get_coursemodule_info($coursemodule)
{
    global $CFG, $DB, $COURSE;
    if ($customlabel = $DB->get_record('customlabel', array('id' => $coursemodule->instance), 'id, labelclass, intro, title, name, content, processedcontent')) {
        // Check label subtype is still installed
        if (!is_dir($CFG->dirroot . '/mod/customlabel/type/' . $customlabel->labelclass)) {
            course_delete_module($coursemodule->id);
            customlabel_delete_instance($customlabel->id);
            rebuild_course_cache($COURSE);
            return;
        }
        $instance = customlabel_load_class($customlabel, $customlabel->labelclass);
        $info = new stdClass();
        $info->name = $customlabel->name;
        $info->extra = '';
        // $customcontent = json_decode(base64_decode($customlabel->content));
        $info->extra = urlencode($customlabel->title);
        return $info;
    } else {
        return null;
    }
}
예제 #19
0
 public function test_hook_course_module_deleted()
 {
     $this->resetAfterTest();
     $dg = $this->getDataGenerator();
     $ccg = $dg->get_plugin_generator('core_competency');
     $u1 = $dg->create_user();
     $framework = $ccg->create_framework();
     $comp1 = $ccg->create_competency(['competencyframeworkid' => $framework->get_id()]);
     $comp2 = $ccg->create_competency(['competencyframeworkid' => $framework->get_id()]);
     $c1 = $dg->create_course();
     $cc1a = $ccg->create_course_competency(['competencyid' => $comp1->get_id(), 'courseid' => $c1->id]);
     $cc1b = $ccg->create_course_competency(['competencyid' => $comp2->get_id(), 'courseid' => $c1->id]);
     $assign1a = $dg->create_module('assign', ['course' => $c1]);
     $assign1b = $dg->create_module('assign', ['course' => $c1]);
     $cmc1a = $ccg->create_course_module_competency(['competencyid' => $comp1->get_id(), 'cmid' => $assign1a->cmid]);
     $cmc1b = $ccg->create_course_module_competency(['competencyid' => $comp1->get_id(), 'cmid' => $assign1b->cmid]);
     $ucc1a = $ccg->create_user_competency_course(['competencyid' => $comp1->get_id(), 'courseid' => $c1->id, 'userid' => $u1->id]);
     $ucc1b = $ccg->create_user_competency_course(['competencyid' => $comp2->get_id(), 'courseid' => $c1->id, 'userid' => $u1->id]);
     $c2 = $dg->create_course();
     $cc2a = $ccg->create_course_competency(['competencyid' => $comp1->get_id(), 'courseid' => $c2->id]);
     $cc2b = $ccg->create_course_competency(['competencyid' => $comp2->get_id(), 'courseid' => $c2->id]);
     $assign2a = $dg->create_module('assign', ['course' => $c2]);
     $assign2b = $dg->create_module('assign', ['course' => $c2]);
     $cmc2a = $ccg->create_course_module_competency(['competencyid' => $comp1->get_id(), 'cmid' => $assign2a->cmid]);
     $cmc2b = $ccg->create_course_module_competency(['competencyid' => $comp1->get_id(), 'cmid' => $assign2b->cmid]);
     $ucc2a = $ccg->create_user_competency_course(['competencyid' => $comp1->get_id(), 'courseid' => $c2->id, 'userid' => $u1->id]);
     $ucc2b = $ccg->create_user_competency_course(['competencyid' => $comp2->get_id(), 'courseid' => $c2->id, 'userid' => $u1->id]);
     course_delete_module($assign1b->cmid);
     $this->assertEquals(2, course_competency::count_records(['courseid' => $c1->id]));
     $this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign1a->cmid]));
     $this->assertEquals(0, course_module_competency::count_records(['cmid' => $assign1b->cmid]));
     $this->assertEquals(2, user_competency_course::count_records(['courseid' => $c1->id]));
     $this->assertEquals(2, course_competency::count_records(['courseid' => $c2->id]));
     $this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2a->cmid]));
     $this->assertEquals(1, course_module_competency::count_records(['cmid' => $assign2b->cmid]));
     $this->assertEquals(2, user_competency_course::count_records(['courseid' => $c2->id, 'userid' => $u1->id]));
 }
예제 #20
0
 /**
  * Test the cleanup task.
  */
 public function test_cleanup_task()
 {
     global $DB;
     set_config('coursebinexpiry', WEEKSECS, 'tool_recyclebin');
     // Delete the quiz.
     course_delete_module($this->quiz->cmid);
     // Now, run the course module deletion adhoc task.
     phpunit_util::run_all_adhoc_tasks();
     // Set deleted date to the distant past.
     $recyclebin = new \tool_recyclebin\course_bin($this->course->id);
     foreach ($recyclebin->get_items() as $item) {
         $item->timecreated = time() - WEEKSECS;
         $DB->update_record('tool_recyclebin_course', $item);
     }
     // Create another module we are going to delete, but not alter the time it was placed in the recycle bin.
     $book = $this->getDataGenerator()->get_plugin_generator('mod_book')->create_instance(array('course' => $this->course->id));
     course_delete_module($book->cmid);
     // Now, run the course module deletion adhoc task.
     phpunit_util::run_all_adhoc_tasks();
     // Should have 2 items now.
     $this->assertEquals(2, count($recyclebin->get_items()));
     // Execute cleanup task.
     $this->expectOutputRegex("/\\[tool_recyclebin\\] Deleting item '\\d+' from the course recycle bin/");
     $task = new \tool_recyclebin\task\cleanup_course_bin();
     $task->execute();
     // Should only have the book as it was not due to be deleted.
     $items = $recyclebin->get_items();
     $this->assertEquals(1, count($items));
     $deletedbook = reset($items);
     $this->assertEquals($book->name, $deletedbook->name);
 }
예제 #21
0
 /**
  * Tests for event related to course module delete.
  */
 public function test_course_module_deleted_event()
 {
     global $USER, $DB;
     $this->resetAfterTest();
     // Create and delete a module.
     $sink = $this->redirectEvents();
     $modinfo = $this->create_specific_module_test('forum');
     $cm = $DB->get_record('course_modules', array('id' => $modinfo->coursemodule), '*', MUST_EXIST);
     course_delete_module($modinfo->coursemodule);
     $events = $sink->get_events();
     $event = array_pop($events);
     // delete module event.;
     $sink->close();
     // Validate event data.
     $this->assertInstanceOf('\\core\\event\\course_module_deleted', $event);
     $this->assertEquals($cm->id, $event->objectid);
     $this->assertEquals($USER->id, $event->userid);
     $this->assertEquals('course_modules', $event->objecttable);
     $this->assertEquals(null, $event->get_url());
     $this->assertEquals($cm, $event->get_record_snapshot('course_modules', $cm->id));
     // Test legacy data.
     $this->assertSame('mod_deleted', $event->get_legacy_eventname());
     $eventdata = new stdClass();
     $eventdata->modulename = 'forum';
     $eventdata->cmid = $cm->id;
     $eventdata->courseid = $cm->course;
     $eventdata->userid = $USER->id;
     $this->assertEventLegacyData($eventdata, $event);
     $arr = array($cm->course, 'course', "delete mod", "view.php?id={$cm->course}", "forum {$cm->instance}", $cm->id);
     $this->assertEventLegacyLogData($arr, $event);
 }
예제 #22
0
function RWSADQuiz()
{
    global $CFG;
    global $RWSLB;
    RWSCMAuth();
    RWSCRAuth();
    RWSCMUSvc();
    RWSCMMaint();
    $r_pm = RWSGSOpt("quizid", PARAM_ALPHANUM);
    if ($r_pm === false || strlen($r_pm) == 0) {
        RWSSErr("2067");
    }
    $r_qzmi = intval($r_pm);
    $r_rcd = RWSCMUQuiz($r_qzmi);
    $r_cid = $r_rcd->course;
    RWSCMUCourse($r_cid, true);
    if (respondusws_floatcompare($CFG->version, 2013051400, 2) >= 0) {
        course_delete_module($r_qzmi);
    } else {
        if (!quiz_delete_instance($r_rcd->instance)) {
            RWSSErr("2068");
        }
        if (!delete_course_module($r_qzmi)) {
            RWSSErr("2069");
        }
        if (!delete_mod_from_section($r_qzmi, $r_rcd->section)) {
            RWSSErr("2070");
        }
    }
    if ($RWSLB->mok) {
        lockdown_delete_options($r_rcd->instance);
    } else {
        if ($RWSLB->bok) {
            lockdown_delete_options($r_rcd->instance);
        }
    }
    rebuild_course_cache($r_cid);
    RWSSStat("1003");
}
예제 #23
0
 public function test_upgrade_offline_setaskment()
 {
     global $DB, $CFG;
     $commentconfig = false;
     if (!empty($CFG->usecomments)) {
         $commentconfig = $CFG->usecomments;
     }
     $CFG->usecomments = false;
     $this->setUser($this->editingteachers[0]);
     $generator = $this->getDataGenerator()->get_plugin_generator('mod_setaskment');
     $params = array('course' => $this->course->id, 'setaskmenttype' => 'offline');
     $setaskment = $generator->create_instance($params);
     $this->setAdminUser();
     $log = '';
     $upgrader = new setask_upgrade_manager();
     $this->assertTrue($upgrader->upgrade_setaskment($setaskment->id, $log));
     $record = $DB->get_record('setask', array('course' => $this->course->id));
     $cm = get_coursemodule_from_instance('setask', $record->id);
     $context = context_module::instance($cm->id);
     $setask = new setask($context, $cm, $this->course);
     $plugin = $setask->get_submission_plugin_by_type('onlinetext');
     $this->assertEmpty($plugin->is_enabled());
     $plugin = $setask->get_submission_plugin_by_type('comments');
     $this->assertEmpty($plugin->is_enabled());
     $plugin = $setask->get_submission_plugin_by_type('file');
     $this->assertEmpty($plugin->is_enabled());
     $plugin = $setask->get_feedback_plugin_by_type('comments');
     $this->assertNotEmpty($plugin->is_enabled());
     $plugin = $setask->get_feedback_plugin_by_type('file');
     $this->assertEmpty($plugin->is_enabled());
     $plugin = $setask->get_feedback_plugin_by_type('offline');
     $this->assertEmpty($plugin->is_enabled());
     $CFG->usecomments = $commentconfig;
     course_delete_module($cm->id);
 }
예제 #24
0
 public function test_rating()
 {
     global $USER, $DB;
     $this->resetAfterTest();
     $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng');
     $course = $this->get_new_course();
     $course2 = $this->get_new_course();
     $suser = $this->get_new_user('student', $course->id);
     $this->setAdminUser();
     $forum = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10));
     $forum2 = $this->get_new_forumng($course->id, array('name' => 'TEST2', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_NO_RATING));
     $forum3 = $this->get_new_forumng($course2->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10));
     $did1 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id));
     $did2 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id));
     $did3 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id));
     $did4 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id));
     // Add rating to all 3 discussions.
     $rm = new rating_manager();
     $params = new stdClass();
     $params->context = $forum->get_context();
     $params->component = 'mod_forumng';
     $params->ratingarea = 'post';
     $params->scaleid = $forum->get_rating_scale();
     $params->userid = $USER->id;
     $params->itemid = $did1[1];
     $rating = new rating($params);
     $rating->update_rating(5);
     $params->itemid = $did2[1];
     $rating = new rating($params);
     $rating->update_rating(5);
     $params->itemid = $did3[1];
     $rating = new rating($params);
     $rating->update_rating(5);
     // Check rating object gets added where expected.
     $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, false, false);
     $ratings = $post->get_ratings();
     $this->assertNotNull($ratings);
     $this->assertEquals($did1[1], $ratings->itemid);
     $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, true, false);
     $ratings = $post->get_ratings();
     $this->assertNotNull($ratings);
     $this->assertEquals($did1[1], $ratings->itemid);
     $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, true, true);
     $ratings = $post->get_ratings();
     $this->assertNotNull($ratings);
     $this->assertEquals($did1[1], $ratings->itemid);
     $ratedposts = $forum->get_all_posts_by_user($suser->id, null, 'fp.id', null, null, true);
     $this->assertCount(3, $ratedposts);
     $allposts = $forum->get_all_posts_by_user($suser->id, null);
     $this->assertCount(4, $allposts);
     $this->assertNotNull($allposts[$did1[1]]->get_ratings());
     // Update grades (does nothing).
     $forum->update_grades();
     // Enable rating grading, forumng_update_instance() should update grades.
     forumng_update_instance((object) array('instance' => $forum->get_id(), 'grading' => mod_forumng::GRADING_SUM));
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id);
     // Note sum is set to 10 not 15 as max grade is 10.
     $this->assertEquals(10, abs($grades->items[0]->grades[$suser->id]->grade));
     // Enable rating grading, forumng_update_instance() should update grades.
     forumng_update_instance((object) array('instance' => $forum->get_id(), 'grading' => mod_forumng::GRADING_COUNT));
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id);
     $this->assertEquals(3, abs($grades->items[0]->grades[$suser->id]->grade));
     // Check get_rated_posts_by_user.
     $extrapost = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser->id, 'created' => 1388589745));
     $extraposts = $forum->get_rated_posts_by_user($forum, $suser->id, -1, 'fp.id', null, null);
     $this->assertCount(0, $extraposts);
     $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null);
     $this->assertCount(3, $extraposts);
     $params->itemid = $extrapost->id;
     $rating = new rating($params);
     $rating->update_rating(10);
     $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null);
     $this->assertCount(4, $extraposts);
     // Now filter out the 'old' extrapost.
     $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null, 1388600000);
     $this->assertCount(3, $extraposts);
     // Check discussion delete.
     $discuss = mod_forumng_discussion::get_from_id($did1[0], mod_forumng::CLONE_DIRECT);
     $discuss->permanently_delete();
     $rating = $DB->get_record('rating', array('itemid' => $did1[1]));
     $this->assertFalse($rating);
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id);
     $this->assertEquals(2, abs($grades->items[0]->grades[$suser->id]->grade));
     // Check discussion move.
     $discuss = mod_forumng_discussion::get_from_id($did2[0], mod_forumng::CLONE_DIRECT);
     $discuss->move($forum2, 0);
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id);
     $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade));
     forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_COUNT, 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10));
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $suser->id);
     $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade));
     $rating = $DB->get_record('rating', array('itemid' => $did2[1]));
     $this->assertNotEmpty($rating);
     $this->assertEquals($forum2->get_context(true)->id, $rating->contextid);
     // Check discussion copy.
     $discuss = mod_forumng_discussion::get_from_id($did3[0], mod_forumng::CLONE_DIRECT);
     $discuss->copy($forum3, 0);
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id);
     $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade));
     // Check rating didn't copy as forum in another course.
     $ratingtotal = $DB->get_records('rating');
     $this->assertCount(2, $ratingtotal);
     // Check rating does copy to foum in same course.
     $discuss->copy($forum2, 0);
     $ratingtotal = $DB->get_records('rating');
     $this->assertCount(3, $ratingtotal);
     // Check forum deleting.
     course_delete_module($forum->get_course_module_id());
     $ratingtotal = $DB->get_records('rating');
     $this->assertCount(2, $ratingtotal);
     $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id);
     $this->assertEmpty($grades->items);
 }
예제 #25
0
 /**
  * This function converts all of the base settings for an instance of
  * the old setaskment to the new format. Then it calls each of the plugins
  * to see if they can help upgrade this setaskment.
  * @param int $oldsetaskmentid (don't rely on the old setaskment type even being installed)
  * @param string $log This string gets appended to during the conversion process
  * @return bool true or false
  */
 public function upgrade_setaskment($oldsetaskmentid, &$log)
 {
     global $DB, $CFG, $USER;
     // Steps to upgrade an setaskment.
     core_php_time_limit::raise(ASSIGN_MAX_UPGRADE_TIME_SECS);
     // Get the module details.
     $oldmodule = $DB->get_record('modules', array('name' => 'setaskment'), '*', MUST_EXIST);
     $params = array('module' => $oldmodule->id, 'instance' => $oldsetaskmentid);
     $oldcoursemodule = $DB->get_record('course_modules', $params, '*', MUST_EXIST);
     $oldcontext = context_module::instance($oldcoursemodule->id);
     // We used to check for admin capability, but since Moodle 2.7 this is called
     // during restore of a mod_setaskment module.
     // Also note that we do not check for any mod_setaskment capabilities, because they can
     // be removed so that users don't add new instances of the broken old thing.
     if (!has_capability('mod/setask:addinstance', $oldcontext)) {
         $log = get_string('couldnotcreatenewsetaskmentinstance', 'mod_setask');
         return false;
     }
     // First insert an setask instance to get the id.
     $oldsetaskment = $DB->get_record('setaskment', array('id' => $oldsetaskmentid), '*', MUST_EXIST);
     $oldversion = get_config('setaskment_' . $oldsetaskment->setaskmenttype, 'version');
     $data = new stdClass();
     $data->course = $oldsetaskment->course;
     $data->name = $oldsetaskment->name;
     $data->intro = $oldsetaskment->intro;
     $data->introformat = $oldsetaskment->introformat;
     $data->alwaysshowdescription = 1;
     $data->sendnotifications = $oldsetaskment->emailteachers;
     $data->sendlatenotifications = $oldsetaskment->emailteachers;
     $data->duedate = $oldsetaskment->timedue;
     $data->allowsubmissionsfromdate = $oldsetaskment->timeavailable;
     $data->grade = $oldsetaskment->grade;
     $data->submissiondrafts = $oldsetaskment->resubmit;
     $data->requiresubmissionstatement = 0;
     $data->markingworkflow = 0;
     $data->markingallocation = 0;
     $data->cutoffdate = 0;
     // New way to specify no late submissions.
     if ($oldsetaskment->preventlate) {
         $data->cutoffdate = $data->duedate;
     }
     $data->teamsubmission = 0;
     $data->requireallteammemberssubmit = 0;
     $data->teamsubmissiongroupingid = 0;
     $data->blindmarking = 0;
     $data->attemptreopenmethod = 'none';
     $data->maxattempts = ASSIGN_UNLIMITED_ATTEMPTS;
     $newsetaskment = new setask(null, null, null);
     if (!$newsetaskment->add_instance($data, false)) {
         $log = get_string('couldnotcreatenewsetaskmentinstance', 'mod_setask');
         return false;
     }
     // Now create a new coursemodule from the old one.
     $newmodule = $DB->get_record('modules', array('name' => 'setask'), '*', MUST_EXIST);
     $newcoursemodule = $this->duplicate_course_module($oldcoursemodule, $newmodule->id, $newsetaskment->get_instance()->id);
     if (!$newcoursemodule) {
         $log = get_string('couldnotcreatenewcoursemodule', 'mod_setask');
         return false;
     }
     // Convert the base database tables (setaskment, submission, grade).
     // These are used to store information in case a rollback is required.
     $gradingarea = null;
     $gradingdefinitions = null;
     $gradeidmap = array();
     $completiondone = false;
     $gradesdone = false;
     // From this point we want to rollback on failure.
     $rollback = false;
     try {
         $newsetaskment->set_context(context_module::instance($newcoursemodule->id));
         // The course module has now been created - time to update the core tables.
         // Copy intro files.
         $newsetaskment->copy_area_files_for_upgrade($oldcontext->id, 'mod_setaskment', 'intro', 0, $newsetaskment->get_context()->id, 'mod_setask', 'intro', 0);
         // Get the plugins to do their bit.
         foreach ($newsetaskment->get_submission_plugins() as $plugin) {
             if ($plugin->can_upgrade($oldsetaskment->setaskmenttype, $oldversion)) {
                 $plugin->enable();
                 if (!$plugin->upgrade_settings($oldcontext, $oldsetaskment, $log)) {
                     $rollback = true;
                 }
             } else {
                 $plugin->disable();
             }
         }
         foreach ($newsetaskment->get_feedback_plugins() as $plugin) {
             if ($plugin->can_upgrade($oldsetaskment->setaskmenttype, $oldversion)) {
                 $plugin->enable();
                 if (!$plugin->upgrade_settings($oldcontext, $oldsetaskment, $log)) {
                     $rollback = true;
                 }
             } else {
                 $plugin->disable();
             }
         }
         // See if there is advanced grading upgrades required.
         $gradingarea = $DB->get_record('grading_areas', array('contextid' => $oldcontext->id, 'areaname' => 'submission'), '*', IGNORE_MISSING);
         if ($gradingarea) {
             $params = array('id' => $gradingarea->id, 'contextid' => $newsetaskment->get_context()->id, 'component' => 'mod_setask', 'areaname' => 'submissions');
             $DB->update_record('grading_areas', $params);
             $gradingdefinitions = $DB->get_records('grading_definitions', array('areaid' => $gradingarea->id));
         }
         // Upgrade availability data.
         \core_availability\info::update_dependency_id_across_course($newcoursemodule->course, 'course_modules', $oldcoursemodule->id, $newcoursemodule->id);
         // Upgrade completion data.
         $DB->set_field('course_modules_completion', 'coursemoduleid', $newcoursemodule->id, array('coursemoduleid' => $oldcoursemodule->id));
         $allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance' => $oldcoursemodule->id));
         foreach ($allcriteria as $criteria) {
             $criteria->module = 'setask';
             $criteria->moduleinstance = $newcoursemodule->id;
             $DB->update_record('course_completion_criteria', $criteria);
         }
         $completiondone = true;
         // Migrate log entries so we don't lose them.
         $logparams = array('cmid' => $oldcoursemodule->id, 'course' => $oldcoursemodule->course);
         $DB->set_field('log', 'module', 'setask', $logparams);
         $DB->set_field('log', 'cmid', $newcoursemodule->id, $logparams);
         // Copy all the submission data (and get plugins to do their bit).
         $oldsubmissions = $DB->get_records('setaskment_submissions', array('setaskment' => $oldsetaskmentid));
         foreach ($oldsubmissions as $oldsubmission) {
             $submission = new stdClass();
             $submission->setaskment = $newsetaskment->get_instance()->id;
             $submission->userid = $oldsubmission->userid;
             $submission->timecreated = $oldsubmission->timecreated;
             $submission->timemodified = $oldsubmission->timemodified;
             $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
             // Because in mod_setaskment there could only be one submission per student, it is always the latest.
             $submission->latest = 1;
             $submission->id = $DB->insert_record('setask_submission', $submission);
             if (!$submission->id) {
                 $log .= get_string('couldnotinsertsubmission', 'mod_setask', $submission->userid);
                 $rollback = true;
             }
             foreach ($newsetaskment->get_submission_plugins() as $plugin) {
                 if ($plugin->can_upgrade($oldsetaskment->setaskmenttype, $oldversion)) {
                     if (!$plugin->upgrade($oldcontext, $oldsetaskment, $oldsubmission, $submission, $log)) {
                         $rollback = true;
                     }
                 }
             }
             if ($oldsubmission->timemarked) {
                 // Submission has been graded - create a grade record.
                 $grade = new stdClass();
                 $grade->setaskment = $newsetaskment->get_instance()->id;
                 $grade->userid = $oldsubmission->userid;
                 $grade->grader = $oldsubmission->teacher;
                 $grade->timemodified = $oldsubmission->timemarked;
                 $grade->timecreated = $oldsubmission->timecreated;
                 $grade->grade = $oldsubmission->grade;
                 if ($oldsubmission->mailed) {
                     // The mailed flag goes in the flags table.
                     $flags = new stdClass();
                     $flags->userid = $oldsubmission->userid;
                     $flags->setaskment = $newsetaskment->get_instance()->id;
                     $flags->mailed = 1;
                     $DB->insert_record('setask_user_flags', $flags);
                 }
                 $grade->id = $DB->insert_record('setask_grades', $grade);
                 if (!$grade->id) {
                     $log .= get_string('couldnotinsertgrade', 'mod_setask', $grade->userid);
                     $rollback = true;
                 }
                 // Copy any grading instances.
                 if ($gradingarea) {
                     $gradeidmap[$grade->id] = $oldsubmission->id;
                     foreach ($gradingdefinitions as $definition) {
                         $params = array('definitionid' => $definition->id, 'itemid' => $oldsubmission->id);
                         $DB->set_field('grading_instances', 'itemid', $grade->id, $params);
                     }
                 }
                 foreach ($newsetaskment->get_feedback_plugins() as $plugin) {
                     if ($plugin->can_upgrade($oldsetaskment->setaskmenttype, $oldversion)) {
                         if (!$plugin->upgrade($oldcontext, $oldsetaskment, $oldsubmission, $grade, $log)) {
                             $rollback = true;
                         }
                     }
                 }
             }
         }
         $newsetaskment->update_calendar($newcoursemodule->id);
         // Reassociate grade_items from the old setaskment instance to the new setask instance.
         // This includes outcome linked grade_items.
         $params = array('setask', $newsetaskment->get_instance()->id, 'setaskment', $oldsetaskment->id);
         $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
         $DB->execute($sql, $params);
         // Create a mapping record to map urls from the old to the new setaskment.
         $mapping = new stdClass();
         $mapping->oldcmid = $oldcoursemodule->id;
         $mapping->oldinstance = $oldsetaskment->id;
         $mapping->newcmid = $newcoursemodule->id;
         $mapping->newinstance = $newsetaskment->get_instance()->id;
         $mapping->timecreated = time();
         $DB->insert_record('setaskment_upgrade', $mapping);
         $gradesdone = true;
     } catch (Exception $exception) {
         $rollback = true;
         $log .= get_string('conversionexception', 'mod_setask', $exception->getMessage());
     }
     if ($rollback) {
         // Roll back the grades changes.
         if ($gradesdone) {
             // Reassociate grade_items from the new setask instance to the old setaskment instance.
             $params = array('setaskment', $oldsetaskment->id, 'setask', $newsetaskment->get_instance()->id);
             $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
             $DB->execute($sql, $params);
         }
         // Roll back the completion changes.
         if ($completiondone) {
             $DB->set_field('course_modules_completion', 'coursemoduleid', $oldcoursemodule->id, array('coursemoduleid' => $newcoursemodule->id));
             $allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance' => $newcoursemodule->id));
             foreach ($allcriteria as $criteria) {
                 $criteria->module = 'setaskment';
                 $criteria->moduleinstance = $oldcoursemodule->id;
                 $DB->update_record('course_completion_criteria', $criteria);
             }
         }
         // Roll back the log changes.
         $logparams = array('cmid' => $newcoursemodule->id, 'course' => $newcoursemodule->course);
         $DB->set_field('log', 'module', 'setaskment', $logparams);
         $DB->set_field('log', 'cmid', $oldcoursemodule->id, $logparams);
         // Roll back the advanced grading update.
         if ($gradingarea) {
             foreach ($gradeidmap as $newgradeid => $oldsubmissionid) {
                 foreach ($gradingdefinitions as $definition) {
                     $DB->set_field('grading_instances', 'itemid', $oldsubmissionid, array('definitionid' => $definition->id, 'itemid' => $newgradeid));
                 }
             }
             $params = array('id' => $gradingarea->id, 'contextid' => $oldcontext->id, 'component' => 'mod_setaskment', 'areaname' => 'submission');
             $DB->update_record('grading_areas', $params);
         }
         $newsetaskment->delete_instance();
         return false;
     }
     // Delete the old setaskment (use object delete).
     $cm = get_coursemodule_from_id('', $oldcoursemodule->id, $oldcoursemodule->course);
     if ($cm) {
         course_delete_module($cm->id);
     }
     rebuild_course_cache($oldcoursemodule->course);
     return true;
 }
예제 #26
0
    /**
     * This function converts all of the base settings for an instance of
     * the old assignment to the new format. Then it calls each of the plugins
     * to see if they can help upgrade this assignment.
     * @param int $oldassignmentid (don't rely on the old assignment type even being installed)
     * @param string $log This string gets appended to during the conversion process
     * @return bool true or false
     */
    public function upgrade_assignment($oldassignmentid, & $log) {
        global $DB, $CFG, $USER;
        // Steps to upgrade an assignment.

        // Is the user the admin? admin check goes here.
        if (!is_siteadmin($USER->id)) {
              return false;
        }

        @set_time_limit(ASSIGN_MAX_UPGRADE_TIME_SECS);

        // Get the module details.
        $oldmodule = $DB->get_record('modules', array('name'=>'assignment'), '*', MUST_EXIST);
        $params = array('module'=>$oldmodule->id, 'instance'=>$oldassignmentid);
        $oldcoursemodule = $DB->get_record('course_modules',
                                           $params,
                                           '*',
                                           MUST_EXIST);
        $oldcontext = context_module::instance($oldcoursemodule->id);

        // First insert an assign instance to get the id.
        $oldassignment = $DB->get_record('assignment', array('id'=>$oldassignmentid), '*', MUST_EXIST);

        $oldversion = get_config('assignment_' . $oldassignment->assignmenttype, 'version');

        $data = new stdClass();
        $data->course = $oldassignment->course;
        $data->name = $oldassignment->name;
        $data->intro = $oldassignment->intro;
        $data->introformat = $oldassignment->introformat;
        $data->alwaysshowdescription = 1;
        $data->sendnotifications = $oldassignment->emailteachers;
        $data->sendlatenotifications = $oldassignment->emailteachers;
        $data->duedate = $oldassignment->timedue;
        $data->allowsubmissionsfromdate = $oldassignment->timeavailable;
        $data->grade = $oldassignment->grade;
        $data->submissiondrafts = $oldassignment->resubmit;
        $data->requiresubmissionstatement = 0;
        $data->cutoffdate = 0;
        // New way to specify no late submissions.
        if ($oldassignment->preventlate) {
            $data->cutoffdate = $data->duedate;
        }
        $data->teamsubmission = 0;
        $data->requireallteammemberssubmit = 0;
        $data->teamsubmissiongroupingid = 0;
        $data->blindmarking = 0;

        $newassignment = new assign(null, null, null);

        if (!$newassignment->add_instance($data, false)) {
            $log = get_string('couldnotcreatenewassignmentinstance', 'mod_assign');
            return false;
        }

        // Now create a new coursemodule from the old one.
        $newmodule = $DB->get_record('modules', array('name'=>'assign'), '*', MUST_EXIST);
        $newcoursemodule = $this->duplicate_course_module($oldcoursemodule,
                                                          $newmodule->id,
                                                          $newassignment->get_instance()->id);
        if (!$newcoursemodule) {
            $log = get_string('couldnotcreatenewcoursemodule', 'mod_assign');
            return false;
        }

        // Convert the base database tables (assignment, submission, grade).

        // These are used to store information in case a rollback is required.
        $gradingarea = null;
        $gradingdefinitions = null;
        $gradeidmap = array();
        $completiondone = false;
        $gradesdone = false;

        // From this point we want to rollback on failure.
        $rollback = false;
        try {
            $newassignment->set_context(context_module::instance($newcoursemodule->id));

            // The course module has now been created - time to update the core tables.

            // Copy intro files.
            $newassignment->copy_area_files_for_upgrade($oldcontext->id, 'mod_assignment', 'intro', 0,
                                            $newassignment->get_context()->id, 'mod_assign', 'intro', 0);

            // Get the plugins to do their bit.
            foreach ($newassignment->get_submission_plugins() as $plugin) {
                if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) {
                    $plugin->enable();
                    if (!$plugin->upgrade_settings($oldcontext, $oldassignment, $log)) {
                        $rollback = true;
                    }
                } else {
                    $plugin->disable();
                }
            }
            foreach ($newassignment->get_feedback_plugins() as $plugin) {
                if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) {
                    $plugin->enable();
                    if (!$plugin->upgrade_settings($oldcontext, $oldassignment, $log)) {
                        $rollback = true;
                    }
                } else {
                    $plugin->disable();
                }
            }

            // See if there is advanced grading upgrades required.
            $gradingarea = $DB->get_record('grading_areas',
                                           array('contextid'=>$oldcontext->id, 'areaname'=>'submission'),
                                           '*',
                                           IGNORE_MISSING);
            if ($gradingarea) {
                $params = array('id'=>$gradingarea->id,
                                'contextid'=>$newassignment->get_context()->id,
                                'component'=>'mod_assign',
                                'areaname'=>'submissions');
                $DB->update_record('grading_areas', $params);
                $gradingdefinitions = $DB->get_records('grading_definitions',
                                                       array('areaid'=>$gradingarea->id));
            }

            // Upgrade availability data.
            $DB->set_field('course_modules_avail_fields',
                           'coursemoduleid',
                           $newcoursemodule->id,
                           array('coursemoduleid'=>$oldcoursemodule->id));
            $DB->set_field('course_modules_availability',
                           'coursemoduleid',
                           $newcoursemodule->id,
                           array('coursemoduleid'=>$oldcoursemodule->id));
            $DB->set_field('course_modules_availability',
                           'sourcecmid',
                           $newcoursemodule->id,
                           array('sourcecmid'=>$oldcoursemodule->id));
            $DB->set_field('course_sections_availability',
                           'sourcecmid',
                           $newcoursemodule->id,
                           array('sourcecmid'=>$oldcoursemodule->id));

            // Upgrade completion data.
            $DB->set_field('course_modules_completion',
                           'coursemoduleid',
                           $newcoursemodule->id,
                           array('coursemoduleid'=>$oldcoursemodule->id));
            $allcriteria = $DB->get_records('course_completion_criteria',
                                            array('moduleinstance'=>$oldcoursemodule->id));
            foreach ($allcriteria as $criteria) {
                $criteria->module = 'assign';
                $criteria->moduleinstance = $newcoursemodule->id;
                $DB->update_record('course_completion_criteria', $criteria);
            }
            $completiondone = true;

            // Migrate log entries so we don't lose them.
            $logparams = array('cmid' => $oldcoursemodule->id, 'course' => $oldcoursemodule->course);
            $DB->set_field('log', 'module', 'assign', $logparams);
            $DB->set_field('log', 'cmid', $newcoursemodule->id, $logparams);

            // Copy all the submission data (and get plugins to do their bit).
            $oldsubmissions = $DB->get_records('assignment_submissions',
                                               array('assignment'=>$oldassignmentid));

            foreach ($oldsubmissions as $oldsubmission) {
                $submission = new stdClass();
                $submission->assignment = $newassignment->get_instance()->id;
                $submission->userid = $oldsubmission->userid;
                $submission->timecreated = $oldsubmission->timecreated;
                $submission->timemodified = $oldsubmission->timemodified;
                $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
                $submission->id = $DB->insert_record('assign_submission', $submission);
                if (!$submission->id) {
                    $log .= get_string('couldnotinsertsubmission', 'mod_assign', $submission->userid);
                    $rollback = true;
                }
                foreach ($newassignment->get_submission_plugins() as $plugin) {
                    if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) {
                        if (!$plugin->upgrade($oldcontext,
                                              $oldassignment,
                                              $oldsubmission,
                                              $submission,
                                              $log)) {
                            $rollback = true;
                        }
                    }
                }
                if ($oldsubmission->timemarked) {
                    // Submission has been graded - create a grade record.
                    $grade = new stdClass();
                    $grade->assignment = $newassignment->get_instance()->id;
                    $grade->userid = $oldsubmission->userid;
                    $grade->grader = $oldsubmission->teacher;
                    $grade->timemodified = $oldsubmission->timemarked;
                    $grade->timecreated = $oldsubmission->timecreated;
                    $grade->grade = $oldsubmission->grade;
                    $grade->mailed = $oldsubmission->mailed;
                    $grade->id = $DB->insert_record('assign_grades', $grade);
                    if (!$grade->id) {
                        $log .= get_string('couldnotinsertgrade', 'mod_assign', $grade->userid);
                        $rollback = true;
                    }

                    // Copy any grading instances.
                    if ($gradingarea) {

                        $gradeidmap[$grade->id] = $oldsubmission->id;

                        foreach ($gradingdefinitions as $definition) {
                            $params = array('definitionid'=>$definition->id,
                                            'itemid'=>$oldsubmission->id);
                            $DB->set_field('grading_instances', 'itemid', $grade->id, $params);
                        }

                    }
                    foreach ($newassignment->get_feedback_plugins() as $plugin) {
                        if ($plugin->can_upgrade($oldassignment->assignmenttype, $oldversion)) {
                            if (!$plugin->upgrade($oldcontext,
                                                  $oldassignment,
                                                  $oldsubmission,
                                                  $grade,
                                                  $log)) {
                                $rollback = true;
                            }
                        }
                    }
                }
            }

            $newassignment->update_calendar($newcoursemodule->id);

            // Reassociate grade_items from the old assignment instance to the new assign instance.
            // This includes outcome linked grade_items.
            $params = array('assign', $newassignment->get_instance()->id, 'assignment', $oldassignment->id);
            $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
            $DB->execute($sql, $params);

            $gradesdone = true;

        } catch (Exception $exception) {
            $rollback = true;
            $log .= get_string('conversionexception', 'mod_assign', $exception->error);
        }

        if ($rollback) {
            // Roll back the grades changes.
            if ($gradesdone) {
                // Reassociate grade_items from the new assign instance to the old assignment instance.
                $params = array('assignment', $oldassignment->id, 'assign', $newassignment->get_instance()->id);
                $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
                $DB->execute($sql, $params);
            }
            // Roll back the completion changes.
            if ($completiondone) {
                $DB->set_field('course_modules_completion',
                               'coursemoduleid',
                               $oldcoursemodule->id,
                               array('coursemoduleid'=>$newcoursemodule->id));

                $allcriteria = $DB->get_records('course_completion_criteria',
                                                array('moduleinstance'=>$newcoursemodule->id));
                foreach ($allcriteria as $criteria) {
                    $criteria->module = 'assignment';
                    $criteria->moduleinstance = $oldcoursemodule->id;
                    $DB->update_record('course_completion_criteria', $criteria);
                }
            }
            // Roll back the log changes.
            $logparams = array('cmid' => $newcoursemodule->id, 'course' => $newcoursemodule->course);
            $DB->set_field('log', 'module', 'assignment', $logparams);
            $DB->set_field('log', 'cmid', $oldcoursemodule->id, $logparams);
            // Roll back the advanced grading update.
            if ($gradingarea) {
                foreach ($gradeidmap as $newgradeid => $oldsubmissionid) {
                    foreach ($gradingdefinitions as $definition) {
                        $DB->set_field('grading_instances',
                                       'itemid',
                                       $oldsubmissionid,
                                       array('definitionid'=>$definition->id, 'itemid'=>$newgradeid));
                    }
                }
                $params = array('id'=>$gradingarea->id,
                                'contextid'=>$oldcontext->id,
                                'component'=>'mod_assignment',
                                'areaname'=>'submission');
                $DB->update_record('grading_areas', $params);
            }
            $newassignment->delete_instance();

            return false;
        }
        // Delete the old assignment (use object delete).
        $cm = get_coursemodule_from_id('', $oldcoursemodule->id, $oldcoursemodule->course);
        if ($cm) {
            course_delete_module($cm->id);
        }
        rebuild_course_cache($oldcoursemodule->course);
        return true;
    }
예제 #27
0
    /**
     * Deletes a list of provided module instances.
     *
     * @param array $cmids the course module ids
     * @since Moodle 2.5
     */
    public static function delete_modules($cmids) {
        global $CFG, $DB;

        // Require course file containing the course delete module function.
        require_once($CFG->dirroot . "/course/lib.php");

        // Clean the parameters.
        $params = self::validate_parameters(self::delete_modules_parameters(), array('cmids' => $cmids));

        // Keep track of the course ids we have performed a capability check on to avoid repeating.
        $arrcourseschecked = array();

        foreach ($params['cmids'] as $cmid) {
            // Get the course module.
            $cm = $DB->get_record('course_modules', array('id' => $cmid), '*', MUST_EXIST);

            // Check if we have not yet confirmed they have permission in this course.
            if (!in_array($cm->course, $arrcourseschecked)) {
                // Ensure the current user has required permission in this course.
                $context = context_course::instance($cm->course);
                self::validate_context($context);
                // Add to the array.
                $arrcourseschecked[] = $cm->course;
            }

            // Ensure they can delete this module.
            $modcontext = context_module::instance($cm->id);
            require_capability('moodle/course:manageactivities', $modcontext);

            // Delete the module.
            course_delete_module($cm->id);
        }
    }
예제 #28
0
 public function test_async_section_deletion_hook_implemented()
 {
     // Async section deletion (provided section contains modules), depends on the 'true' being returned by at least one plugin
     // implementing the 'course_module_adhoc_deletion_recommended' hook. In core, is implemented by the course recyclebin,
     // which will only return true if the plugin is enabled. To make sure async deletion occurs, this test enables recyclebin.
     global $DB, $USER;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     // Ensure recyclebin is enabled.
     set_config('coursebinenable', true, 'tool_recyclebin');
     // Create course, module and context.
     $generator = $this->getDataGenerator();
     $course = $generator->create_course(['numsections' => 4, 'format' => 'topics'], ['createsections' => true]);
     $assign0 = $generator->create_module('assign', ['course' => $course, 'section' => 2]);
     $assign1 = $generator->create_module('assign', ['course' => $course, 'section' => 2]);
     $assign2 = $generator->create_module('assign', ['course' => $course, 'section' => 2]);
     $assign3 = $generator->create_module('assign', ['course' => $course, 'section' => 0]);
     // Delete empty section. No difference from normal, synchronous behaviour.
     $this->assertTrue(course_delete_section($course, 4, false, true));
     $this->assertEquals(3, course_get_format($course)->get_course()->numsections);
     // Delete a module in section 2 (using async). Need to verify this doesn't generate two tasks when we delete
     // the section in the next step.
     course_delete_module($assign2->cmid, true);
     // Confirm that the module is pending deletion in its current section.
     $section = $DB->get_record('course_sections', ['course' => $course->id, 'section' => '2']);
     // For event comparison.
     $this->assertEquals(true, $DB->record_exists('course_modules', ['id' => $assign2->cmid, 'deletioninprogress' => 1, 'section' => $section->id]));
     // Now, delete section 2.
     $this->assertFalse(course_delete_section($course, 2, false, true));
     // Non-empty section, no forcedelete, so no change.
     $sink = $this->redirectEvents();
     // To capture the event.
     $this->assertTrue(course_delete_section($course, 2, true, true));
     // Now, confirm that:
     // a) the section's modules have been flagged for deletion and moved to section 0 and;
     // b) the section has been deleted and;
     // c) course_section_deleted event has been fired. The course_module_deleted events will only fire once they have been
     // removed from section 0 via the adhoc task.
     // Modules should have been flagged for deletion and moved to section 0.
     $sectionid = $DB->get_field('course_sections', 'id', ['course' => $course->id, 'section' => 0]);
     $this->assertEquals(3, $DB->count_records('course_modules', ['section' => $sectionid, 'deletioninprogress' => 1]));
     // Confirm the section has been deleted.
     $this->assertEquals(2, course_get_format($course)->get_course()->numsections);
     // Check event fired.
     $events = $sink->get_events();
     $event = array_pop($events);
     $sink->close();
     $this->assertInstanceOf('\\core\\event\\course_section_deleted', $event);
     $this->assertEquals($section->id, $event->objectid);
     $this->assertEquals($USER->id, $event->userid);
     $this->assertEquals('course_sections', $event->objecttable);
     $this->assertEquals(null, $event->get_url());
     $this->assertEquals($section, $event->get_record_snapshot('course_sections', $section->id));
     // Now, run the adhoc task to delete the modules from section 0.
     $sink = $this->redirectEvents();
     // To capture the events.
     phpunit_util::run_all_adhoc_tasks();
     // Confirm the modules have been deleted.
     list($insql, $assignids) = $DB->get_in_or_equal([$assign0->cmid, $assign1->cmid, $assign2->cmid]);
     $cmcount = $DB->count_records_select('course_modules', 'id ' . $insql, $assignids);
     $this->assertEmpty($cmcount);
     // Confirm other modules in section 0 still remain.
     $this->assertEquals(1, $DB->count_records('course_modules', ['id' => $assign3->cmid]));
     // Confirm that events were generated for all 3 of the modules.
     $events = $sink->get_events();
     $sink->close();
     $count = 0;
     while (!empty($events)) {
         $event = array_pop($events);
         if ($event instanceof \core\event\course_module_deleted && in_array($event->objectid, [$assign0->cmid, $assign1->cmid, $assign2->cmid])) {
             $count++;
         }
     }
     $this->assertEquals(3, $count);
 }
예제 #29
0
파일: lib.php 프로젝트: EsdrasCaleb/moodle
 /**
  * Deletes a section
  *
  * Do not call this function directly, instead call {@link course_delete_section()}
  *
  * @param int|stdClass|section_info $section
  * @param bool $forcedeleteifnotempty if set to false section will not be deleted if it has modules in it.
  * @return bool whether section was deleted
  */
 public function delete_section($section, $forcedeleteifnotempty = false)
 {
     global $DB;
     if (!$this->uses_sections()) {
         // Not possible to delete section if sections are not used.
         return false;
     }
     if (!is_object($section)) {
         $section = $DB->get_record('course_sections', array('course' => $this->get_courseid(), 'section' => $section), 'id,section,sequence,summary');
     }
     if (!$section || !$section->section) {
         // Not possible to delete 0-section.
         return false;
     }
     if (!$forcedeleteifnotempty && (!empty($section->sequence) || !empty($section->summary))) {
         return false;
     }
     $course = $this->get_course();
     // Remove the marker if it points to this section.
     if ($section->section == $course->marker) {
         course_set_marker($course->id, 0);
     }
     $lastsection = $DB->get_field_sql('SELECT max(section) from {course_sections}
                         WHERE course = ?', array($course->id));
     // Find out if we need to descrease the 'numsections' property later.
     $courseformathasnumsections = array_key_exists('numsections', $this->get_format_options());
     $decreasenumsections = $courseformathasnumsections && $section->section <= $course->numsections;
     // Move the section to the end.
     move_section_to($course, $section->section, $lastsection, true);
     // Delete all modules from the section.
     foreach (preg_split('/,/', $section->sequence, -1, PREG_SPLIT_NO_EMPTY) as $cmid) {
         course_delete_module($cmid);
     }
     // Delete section and it's format options.
     $DB->delete_records('course_format_options', array('sectionid' => $section->id));
     $DB->delete_records('course_sections', array('id' => $section->id));
     rebuild_course_cache($course->id, true);
     // Descrease 'numsections' if needed.
     if ($decreasenumsections) {
         $this->update_course_format_options(array('numsections' => $course->numsections - 1));
     }
     return true;
 }
예제 #30
0
 /**
  * Called after the mod has set itself up, to finish off any course module settings
  * (set instance id, add to correct section, set visibility, etc.) and send the response
  *
  * @param int $instanceid id returned by the mod when it was created
  */
 protected function finish_setup_course_module($instanceid)
 {
     global $DB, $USER;
     if (!$instanceid) {
         // Something has gone wrong - undo everything we can.
         course_delete_module($this->cm->id);
         throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
     }
     // Note the section visibility
     $visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible;
     $DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id));
     // Rebuild the course cache after update action
     rebuild_course_cache($this->course->id, true);
     $this->course->modinfo = null;
     // Otherwise we will just get the old version back again.
     $sectionid = course_add_cm_to_section($this->course, $this->cm->id, $this->section);
     set_coursemodule_visible($this->cm->id, $visible);
     if (!$visible) {
         $DB->set_field('course_modules', 'visibleold', 1, array('id' => $this->cm->id));
     }
     // retrieve the final info about this module.
     $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.
         course_delete_module($this->cm->id);
         throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
     }
     $mod = $info->get_cm($this->cm->id);
     $mod->groupmodelink = $this->cm->groupmodelink;
     $mod->groupmode = $this->cm->groupmode;
     // Trigger mod_created event with information about this module.
     $eventdata = new stdClass();
     $eventdata->modulename = $mod->modname;
     $eventdata->name = $mod->name;
     $eventdata->cmid = $mod->id;
     $eventdata->courseid = $this->course->id;
     $eventdata->userid = $USER->id;
     events_trigger('mod_created', $eventdata);
     add_to_log($this->course->id, "course", "add mod", "../mod/{$mod->modname}/view.php?id={$mod->id}", "{$mod->modname} {$instanceid}");
     add_to_log($this->course->id, $mod->modname, "add", "view.php?id={$mod->id}", "{$instanceid}", $mod->id);
     $this->send_response($mod);
 }