MDL-21432 backup - now restoring ras/caps and "manual" enrolment plugins.
TODO: Complete the enrolments part and fix current implementation, it's only one skeleton
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
class restore_course_task extends restore_task {
|
||||
|
||||
protected $info; // info related to course gathered from backup file
|
||||
protected $contextid; // course context id
|
||||
|
||||
/**
|
||||
* Constructor - instantiates one object of this class
|
||||
@@ -48,17 +49,29 @@ class restore_course_task extends restore_task {
|
||||
return $this->get_basepath() . '/course';
|
||||
}
|
||||
|
||||
public function get_contextid() {
|
||||
return $this->contextid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all the steps that will be part of this task
|
||||
*/
|
||||
public function build() {
|
||||
|
||||
// TODO: Link all the course steps here
|
||||
// Define the task contextid (the course one)
|
||||
$this->contextid = get_context_instance(CONTEXT_COURSE, $this->get_courseid())->id;
|
||||
|
||||
// Executed conditionally if restoring to new course or deleting or if overwrite_conf setting is enabled
|
||||
if ($this->get_target() == backup::TARGET_NEW_COURSE || $this->get_setting_value('overwrite_conf') == true) {
|
||||
$this->add_step(new restore_course_structure_step('course_info', 'course.xml'));
|
||||
}
|
||||
|
||||
// Restore course role assignments and overrides (internally will observe the role_assignments setting)
|
||||
$this->add_step(new restore_ras_and_caps_structure_step('course_ras_and_caps', 'roles.xml'));
|
||||
|
||||
// Restore course enrolments (plugins and membership)
|
||||
$this->add_step(new restore_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
|
||||
|
||||
// At the end, mark it as built
|
||||
$this->built = true;
|
||||
}
|
||||
|
||||
@@ -558,3 +558,139 @@ class restore_course_structure_step extends restore_structure_step {
|
||||
$this->add_related_files('course', 'legacy', null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Structure step that will read the roles.xml file (at course/activity/block levels)
|
||||
* containig all the role_assignments and overrides for that context. If corresponding to
|
||||
* one mapped role, they will be applied to target context. Will observe the role_assignments
|
||||
* setting to decide if ras are restored.
|
||||
* Note: only ras with component == null are restored as far as the any ra with component
|
||||
* is handled by one enrolment plugin, hence it will createt the ras later
|
||||
*/
|
||||
class restore_ras_and_caps_structure_step extends restore_structure_step {
|
||||
|
||||
protected function define_structure() {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// Observe the role_assignments setting
|
||||
if ($this->get_setting_value('role_assignments')) {
|
||||
$paths[] = new restore_path_element('assignment', '/roles/role_assignments/assignment');
|
||||
}
|
||||
$paths[] = new restore_path_element('override', '/roles/role_overrides/override');
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
public function process_assignment($data) {
|
||||
$data = (object)$data;
|
||||
|
||||
// Check roleid, userid are one of the mapped ones
|
||||
$newroleid = $this->get_mappingid('role', $data->roleid);
|
||||
$newuserid = $this->get_mappingid('user', $data->userid);
|
||||
// If newroleid and newuserid and component is empty assign via API (handles dupes and friends)
|
||||
if ($newroleid && $newuserid && empty($data->component)) {
|
||||
// TODO: role_assign() needs one userid param to be able to specify our restore userid
|
||||
role_assign($newroleid, $newuserid, $this->task->get_contextid());
|
||||
}
|
||||
}
|
||||
|
||||
public function process_override($data) {
|
||||
$data = (object)$data;
|
||||
|
||||
// Check roleid is one of the mapped ones
|
||||
$newroleid = $this->get_mappingid('role', $data->roleid);
|
||||
// If newroleid is valid assign it via API (it handles dupes and so on)
|
||||
if ($newroleid) {
|
||||
// TODO: assign_capability() needs one userid param to be able to specify our restore userid
|
||||
assign_capability($data->capability, $data->permission, $newroleid, $this->task->get_contextid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This structure steps restores the enrol plugins and their underlying
|
||||
* enrolments, performing all the mappings and/or movements required
|
||||
*/
|
||||
class restore_enrolments_structure_step extends restore_structure_step {
|
||||
|
||||
protected function define_structure() {
|
||||
|
||||
$paths = array();
|
||||
|
||||
$paths[] = new restore_path_element('enrol', '/enrolments/enrols/enrol');
|
||||
$paths[] = new restore_path_element('enrolment', '/enrolments/enrols/enrol/user_enrolments/enrolment');
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
public function process_enrol($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id; // We'll need this later
|
||||
|
||||
// TODO: Just one quick process of manual enrol_plugin. Add the rest (complex ones) and fix this
|
||||
if ($data->enrol !== 'manual') {
|
||||
debugging("Skipping '{$data->enrol}' enrolment plugin. Must be implemented", DEBUG_DEVELOPER);
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform various checks to decide what to do with the enrol plugin
|
||||
$installed = array_key_exists($data->enrol, enrol_get_plugins(false));
|
||||
$enabled = enrol_is_enabled($data->enrol);
|
||||
$exists = 0;
|
||||
$roleid = $this->get_mappingid('role', $data->roleid);
|
||||
if ($rec = $DB->get_record('enrol', array('courseid' => $this->get_courseid(), 'enrol' => $data->enrol))) {
|
||||
$exists = $rec->id;
|
||||
}
|
||||
// If installed and enabled, continue processing
|
||||
if ($installed && $enabled) {
|
||||
// If not exists in course and we have a target role mapping
|
||||
if (!$exists && $roleid) {
|
||||
$data->roleid = $roleid;
|
||||
$enrol = enrol_get_plugin($data->enrol);
|
||||
$courserec = $DB->get_record('course', array('id' => $this->get_courseid())); // Requires object, uses only id!!
|
||||
$newitemid = $enrol->add_instance($courserec, array($data));
|
||||
|
||||
// Already exists, user it for enrolments
|
||||
} else {
|
||||
$newitemid = $exists;
|
||||
}
|
||||
|
||||
// Not installed and enabled, map to 0
|
||||
} else {
|
||||
$newitemid = 0;
|
||||
}
|
||||
// Perform the simple mapping and done
|
||||
$this->set_mapping('enrol', $oldid, $newitemid);
|
||||
}
|
||||
|
||||
public function process_enrolment($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
// Process only if parent instance have been mapped
|
||||
if ($enrolid = $this->get_new_parentid('enrol')) {
|
||||
// And only if user is a mapped one
|
||||
if ($userid = $this->get_mappingid('user', $data->userid)) {
|
||||
// TODO: Surely need to use API (enrol_user) here, instead of the current low-level impl
|
||||
// TODO: Note enrol_user() sticks to $USER->id (need to add userid param)
|
||||
$enrolment = new stdclass();
|
||||
$enrolment->enrolid = $enrolid;
|
||||
$enrolment->userid = $userid;
|
||||
if (!$DB->record_exists('user_enrolments', (array)$enrolment)) {
|
||||
$enrolment->status = $data->status;
|
||||
$enrolment->timestart = $data->timestart;
|
||||
$enrolment->timeend = $data->timeend;
|
||||
$enrolment->modifierid = $this->task->get_userid();
|
||||
$enrolment->timecreated = time();
|
||||
$enrolment->timemodified = 0;
|
||||
$DB->insert_record('user_enrolments', $enrolment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -873,8 +873,8 @@ abstract class restore_dbops {
|
||||
foreach ($rs as $recrole) {
|
||||
// Get the complete temp_ids record
|
||||
$role = (object)self::get_backup_ids_record($restoreid, 'role', $recrole->itemid);
|
||||
// If it's one mapped role
|
||||
if (!empty($role->newitemid)) {
|
||||
// If it's one mapped role and we have one name for it
|
||||
if (!empty($role->newitemid) && !empty($role->info['nameincourse'])) {
|
||||
// If role name doesn't exist, add it
|
||||
$rolename = new stdclass();
|
||||
$rolename->roleid = $role->newitemid;
|
||||
|
||||
@@ -54,4 +54,14 @@ class restore_roles_parser_processor extends grouped_parser_processor {
|
||||
restore_dbops::set_backup_ids_record($this->restoreid, $itemname, $itemid, 0, null, $info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide NULL decoding
|
||||
*/
|
||||
public function process_cdata($cdata) {
|
||||
if ($cdata === '$@NULL@$') {
|
||||
return null;
|
||||
}
|
||||
return $cdata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,4 +65,14 @@ class restore_users_parser_processor extends grouped_parser_processor {
|
||||
restore_dbops::set_backup_ids_record($this->restoreid, $itemname, $itemid, 0, $parentitemid, $info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide NULL decoding
|
||||
*/
|
||||
public function process_cdata($cdata) {
|
||||
if ($cdata === '$@NULL@$') {
|
||||
return null;
|
||||
}
|
||||
return $cdata;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user