/** * Update the module info. * This function doesn't check the user capabilities. It updates the course module and the module instance. * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...). * * @param object $cm course module * @param object $moduleinfo module info * @param object $course course of the module * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function. * @return array list of course module and module info. */ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) { global $DB, $CFG; // Attempt to include module library before we make any changes to DB. include_modulelib($moduleinfo->modulename); $moduleinfo->course = $course->id; $moduleinfo = set_moduleinfo_defaults($moduleinfo); if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) { $moduleinfo->groupmode = $cm->groupmode; // Keep original. } // Update course module first. $cm->groupmode = $moduleinfo->groupmode; if (isset($moduleinfo->groupingid)) { $cm->groupingid = $moduleinfo->groupingid; } $completion = new completion_info($course); if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { // Update completion settings. $cm->completion = $moduleinfo->completion; $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber; $cm->completionview = $moduleinfo->completionview; $cm->completionexpected = $moduleinfo->completionexpected; } if (!empty($CFG->enableavailability)) { // This code is used both when submitting the form, which uses a long // name to avoid clashes, and by unit test code which uses the real // name in the table. if (property_exists($moduleinfo, 'availabilityconditionsjson')) { if ($moduleinfo->availabilityconditionsjson !== '') { $cm->availability = $moduleinfo->availabilityconditionsjson; } else { $cm->availability = null; } } else { if (property_exists($moduleinfo, 'availability')) { $cm->availability = $moduleinfo->availability; } } // If there is any availability data, verify it. if ($cm->availability) { $tree = new \core_availability\tree(json_decode($cm->availability)); // Save time and database space by setting null if the only data // is an empty tree. if ($tree->is_empty()) { $cm->availability = null; } } } if (isset($moduleinfo->showdescription)) { $cm->showdescription = $moduleinfo->showdescription; } else { $cm->showdescription = 0; } $DB->update_record('course_modules', $cm); $modcontext = context_module::instance($moduleinfo->coursemodule); // Update embedded links and save files. if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) { $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $moduleinfo->introeditor['text']); $moduleinfo->introformat = $moduleinfo->introeditor['format']; unset($moduleinfo->introeditor); } $updateinstancefunction = $moduleinfo->modulename . "_update_instance"; if (!$updateinstancefunction($moduleinfo, $mform)) { print_error('cannotupdatemod', '', course_get_url($course, $cw->section), $moduleinfo->modulename); } // Make sure visibility is set correctly (in particular in calendar). if (has_capability('moodle/course:activityvisibility', $modcontext)) { set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible); } if (isset($moduleinfo->cmidnumber)) { // Label. // Set cm idnumber - uniqueness is already verified by form validation. set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber); } // Now that module is fully updated, also update completion data if required. // (this will wipe all user completion data and recalculate it) if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { $completion->reset_all_state($cm); } $cm->name = $moduleinfo->name; \core\event\course_module_updated::create_from_cm($cm, $modcontext)->trigger(); $moduleinfo = edit_module_post_actions($moduleinfo, $course); return array($cm, $moduleinfo); }
/** * Update the module info. * This function doesn't check the user capabilities. It updates the course module and the module instance. * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...). * * @param object $cm course module * @param object $moduleinfo module info * @param object $course course of the module * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function. * @return array list of course module and module info. */ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) { global $DB, $CFG; $data = new stdClass(); if ($mform) { $data = $mform->get_data(); } // Attempt to include module library before we make any changes to DB. include_modulelib($moduleinfo->modulename); $moduleinfo->course = $course->id; $moduleinfo = set_moduleinfo_defaults($moduleinfo); if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) { $moduleinfo->groupmode = $cm->groupmode; // Keep original. } // Update course module first. $cm->groupmode = $moduleinfo->groupmode; if (isset($moduleinfo->groupingid)) { $cm->groupingid = $moduleinfo->groupingid; } $completion = new completion_info($course); if ($completion->is_enabled()) { // Completion settings that would affect users who have already completed // the activity may be locked; if so, these should not be updated. if (!empty($moduleinfo->completionunlocked)) { $cm->completion = $moduleinfo->completion; $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber; $cm->completionview = $moduleinfo->completionview; } // The expected date does not affect users who have completed the activity, // so it is safe to update it regardless of the lock status. $cm->completionexpected = $moduleinfo->completionexpected; } if (!empty($CFG->enableavailability)) { // This code is used both when submitting the form, which uses a long // name to avoid clashes, and by unit test code which uses the real // name in the table. if (property_exists($moduleinfo, 'availabilityconditionsjson')) { if ($moduleinfo->availabilityconditionsjson !== '') { $cm->availability = $moduleinfo->availabilityconditionsjson; } else { $cm->availability = null; } } else { if (property_exists($moduleinfo, 'availability')) { $cm->availability = $moduleinfo->availability; } } // If there is any availability data, verify it. if ($cm->availability) { $tree = new \core_availability\tree(json_decode($cm->availability)); // Save time and database space by setting null if the only data // is an empty tree. if ($tree->is_empty()) { $cm->availability = null; } } } if (isset($moduleinfo->showdescription)) { $cm->showdescription = $moduleinfo->showdescription; } else { $cm->showdescription = 0; } $DB->update_record('course_modules', $cm); $modcontext = context_module::instance($moduleinfo->coursemodule); // Update embedded links and save files. if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) { $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $moduleinfo->introeditor['text']); $moduleinfo->introformat = $moduleinfo->introeditor['format']; unset($moduleinfo->introeditor); } // Get the a copy of the grade_item before it is modified incase we need to scale the grades. $oldgradeitem = null; $newgradeitem = null; if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') { // Fetch the grade item before it is updated. $oldgradeitem = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => $moduleinfo->modulename, 'iteminstance' => $moduleinfo->instance, 'itemnumber' => 0, 'courseid' => $moduleinfo->course)); } $updateinstancefunction = $moduleinfo->modulename . "_update_instance"; if (!$updateinstancefunction($moduleinfo, $mform)) { print_error('cannotupdatemod', '', course_get_url($course, $cm->section), $moduleinfo->modulename); } // This needs to happen AFTER the grademin/grademax have already been updated. if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') { // Get the grade_item after the update call the activity to scale the grades. $newgradeitem = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => $moduleinfo->modulename, 'iteminstance' => $moduleinfo->instance, 'itemnumber' => 0, 'courseid' => $moduleinfo->course)); if ($newgradeitem && $oldgradeitem->gradetype == GRADE_TYPE_VALUE && $newgradeitem->gradetype == GRADE_TYPE_VALUE) { $params = array($course, $cm, $oldgradeitem->grademin, $oldgradeitem->grademax, $newgradeitem->grademin, $newgradeitem->grademax); if (!component_callback('mod_' . $moduleinfo->modulename, 'rescale_activity_grades', $params)) { print_error('cannotreprocessgrades', '', course_get_url($course, $cm->section), $moduleinfo->modulename); } } } // Make sure visibility is set correctly (in particular in calendar). if (has_capability('moodle/course:activityvisibility', $modcontext)) { set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible); } if (isset($moduleinfo->cmidnumber)) { // Label. // Set cm idnumber - uniqueness is already verified by form validation. set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber); } // Update module tags. if (core_tag_tag::is_enabled('core', 'course_modules') && isset($moduleinfo->tags)) { core_tag_tag::set_item_tags('core', 'course_modules', $moduleinfo->coursemodule, $modcontext, $moduleinfo->tags); } // Now that module is fully updated, also update completion data if required. // (this will wipe all user completion data and recalculate it) if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) { $completion->reset_all_state($cm); } $cm->name = $moduleinfo->name; \core\event\course_module_updated::create_from_cm($cm, $modcontext)->trigger(); $moduleinfo = edit_module_post_actions($moduleinfo, $course); return array($cm, $moduleinfo); }