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:
Eloy Lafuente
2010-07-21 19:30:15 +00:00
parent 01310dfbed
commit 024c288dab
5 changed files with 172 additions and 3 deletions
+14 -1
View File
@@ -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;
}
+136
View File
@@ -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);
}
}
}
}
}
+2 -2
View File
@@ -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;
}
}