MDL-21432 - backup finished groupings restore + introduced role precheck/execution step

This commit is contained in:
Eloy Lafuente
2010-07-19 14:06:16 +00:00
parent a7ce4231be
commit 71a50b133d
5 changed files with 137 additions and 16 deletions
@@ -40,6 +40,9 @@ class restore_root_task extends restore_task {
// If we haven't preloaded information, load all the included inforef records to temp_ids table
$this->add_step(new restore_load_included_inforef_records('load_inforef_records'));
// If we haven't preloaded information, load all the needed roles to temp_ids_table
$this->add_step(new restore_load_and_map_roles('load_and_map_roles'));
// If we haven't preloaded information and are restoring user info, load all the needed users to temp_ids table
$this->add_step(new restore_load_included_users('load_user_records'));
+67 -4
View File
@@ -108,15 +108,41 @@ class restore_load_included_files extends restore_structure_step {
// load it if needed:
// - it it is one of the annotated inforef files (course/section/activity/block)
// - it is one "user", "group" or "grade" component file
// - it is one "user", "group", "grouping" or "grade" component file (that aren't sent to inforef ever)
$isfileref = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'fileref', $data->id);
$iscomponent = ($data->component == 'user' || $data->component == 'group' || $data->component == 'grade');
$iscomponent = ($data->component == 'user' || $data->component == 'group' ||
$data->component == 'grouping' || $data->component == 'grade');
if ($isfileref || $iscomponent) {
restore_dbops::set_backup_files_record($this->get_restoreid(), $data);
}
}
}
/**
* Execution step that, *conditionally* (if there isn't preloaded information),
* will load all the needed roles to backup_temp_ids. They will be stored with
* "role" itemname. Also it will perform one automatic mapping to roles existing
* in the target site, based in permissions of the user performing the restore,
* archetypes and other bits. At the end, each original role will have its associated
* target role or 0 if it's going to be skipped. Note we wrap everything over one
* restore_dbops method, as far as the same stuff is going to be also executed
* by restore prechecks
*/
class restore_load_and_map_roles extends restore_execution_step {
protected function define_execution() {
if ($this->task->get_preloaded_information()) { // if info is already preloaded, nothing to do
return;
}
$file = $this->get_basepath() . '/roles.xml';
// Load needed toles to temp_ids
restore_dbops::load_roles_to_tempids($this->get_restoreid(), $file);
// Process roles, mapping/skipping. Any error throws exception
restore_dbops::process_included_roles($this->get_restoreid(), $this->task->get_courseid(), $this->task->get_userid(), $this->task->is_samesite());
}
}
/**
* Execution step that, *conditionally* (if there isn't preloaded information
* and users have been selected in settings, will load all the needed users
@@ -243,17 +269,53 @@ class restore_groups_structure_step extends restore_structure_step {
}
public function process_grouping($data) {
debugging('TODO: Grouping restore not implemented. Detected grouping', DEBUG_DEVELOPER);
global $DB;
$data = (object)$data; // handy
$data->courseid = $this->get_courseid();
$oldid = $data->id; // need this saved for later
$restorefiles = false; // Only if we end creating the grouping
// Search if the grouping already exists (by name & description) in the target course
$description_clause = '';
$params = array('courseid' => $this->get_courseid(), 'grname' => $data->name);
if (!empty($data->description)) {
$description_clause = ' AND ' .
$DB->sql_compare_text('description') . ' = ' . $DB->sql_compare_text(':desc');
$params['desc'] = $data->description;
}
if (!$groupingdb = $DB->get_record_sql("SELECT *
FROM {groupings}
WHERE courseid = :courseid
AND name = :grname $description_clause", $params)) {
// grouping doesn't exist, create
$newitemid = $DB->insert_record('groupings', $data);
$restorefiles = true; // We'll restore the files
} else {
// grouping exists, use it
$newitemid = $groupingdb->id;
}
// Save the id mapping
$this->set_mapping('grouping', $oldid, $newitemid, $restorefiles);
}
public function process_grouping_group($data) {
debugging('TODO: Grouping restore not implemented. Detected grouping group', DEBUG_DEVELOPER);
global $DB;
$data = (object)$data;
$data->groupingid = $this->get_new_parentid('grouping'); // Use new parentid
$data->groupid = $this->get_mappingid('group', $data->groupid); // Get from mappings
$DB->insert_record('groupings_groups', $data); // No need to set this mapping (no child info nor files)
}
protected function after_execute() {
// Add group related files, matching with "group" mappings
$this->add_related_files('group', 'icon', 'group');
$this->add_related_files('group', 'description', 'group');
// Add grouping related files, matching with "grouping" mappings
$this->add_related_files('grouping', 'description', 'grouping');
}
}
@@ -339,6 +401,7 @@ class restore_course_structure_step extends restore_structure_step {
// Processing functions go here
public function process_course($data) {
// TODO: don't forget to remap defaultgroupingid
print_object('stopped before processing course. Continue here');
}
+45 -1
View File
@@ -94,6 +94,50 @@ abstract class restore_dbops {
$xmlparser->process();
}
/**
* Load the needed role.xml file to backup_ids table for future reference
*/
public static function load_roles_to_tempids($restoreid, $rolesfile) {
if (!file_exists($rolesfile)) { // Shouldn't happen ever, but...
throw new backup_helper_exception('missing_roles_xml_file', $rolesfile);
}
// Let's parse, custom processor will do its work, sending info to DB
$xmlparser = new progressive_parser();
$xmlparser->set_file($rolesfile);
$xmlprocessor = new restore_roles_parser_processor($restoreid);
$xmlparser->set_processor($xmlprocessor);
$xmlparser->process();
}
/**
* Precheck the loaded roles, return empty array if everything is ok, and
* array with 'errors', 'warnings' elements (suitable to be used by restore_prechecks)
* with any problem found
*/
public static function precheck_included_roles($restoreid, $courseid, $userid, $samesite) {
debugging('implement the roles mapping/skip here. returns errors/warnings array', DEBUG_DEVELOPER);
return array();
}
/**
* Process the loaded roles, looking for their best mapping or skipping
* Any error will cause exception. Note this is one wrapper over
* precheck_included_roles, that contains all the logic, but returns
* errors/warnings instead and is executed as part of the restore prechecks
*/
public static function process_included_roles($restoreid, $courseid, $userid, $samesite) {
global $DB;
// Just let precheck_included_roles() to do all the hard work
$problems = self::precheck_included_roles($restoreid, $courseid, $userid, $samesite);
// With problems of type error, throw exception, shouldn't happen if prechecks executed
if (array_key_exists('errors', $problems)) {
throw new restore_dbops_exception('restore_problems_processing_roles', null, implode(', ', $problems['errors']));
}
}
/**
* Load the needed users.xml file to backup_ids table for future reference
*/
@@ -152,9 +196,9 @@ abstract class restore_dbops {
$params = array($restoreid, $oldcontextid, $component, $filearea, $itemname);
}
$rs = $DB->get_recordset_sql($sql, $params);
$fs = get_file_storage(); // Get moodle file storage
$basepath = $basepath . '/files/';// Get backup file pool base
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $rec) {
$file = (object)unserialize(base64_decode($rec->info));
// ignore root dirs (they are created automatically)
@@ -49,6 +49,15 @@ abstract class restore_prechecks_helper {
$errors = array();
$warnings = array();
// Some handy vars to be used along the prechecks
$samesite = $controller->is_samesite();
$restoreusers = $controller->get_plan()->get_setting('users')->get_value();
$hasmnetusers = (int)$controller->get_info()->mnet_remoteusers;
$restoreid = $controller->get_restoreid();
$courseid = $controller->get_courseid();
$userid = $controller->get_userid();
$inforeffiles = restore_dbops::get_needed_inforef_files($restoreid); // Get all inforef files
// Create temp tables
restore_controller_dbops::create_restore_temp_tables($controller->get_restoreid());
@@ -78,9 +87,6 @@ abstract class restore_prechecks_helper {
}
// If restoring to different site and restoring users and backup has mnet users warn/error
$samesite = $controller->is_samesite();
$restoreusers = $controller->get_plan()->get_setting('users')->get_value();
$hasmnetusers = (int)$controller->get_info()->mnet_remoteusers;
if (!$samesite && $restoreusers && $hasmnetusers) {
// User is admin (can create users at sysctx), warn
if (has_capability('moodle/user:create', get_context_instance(CONTEXT_SYSTEM), $controller->get_userid())) {
@@ -91,16 +97,14 @@ abstract class restore_prechecks_helper {
}
}
// Load all the inforef files, we are going to need them
foreach ($inforeffiles as $inforeffile) {
restore_dbops::load_inforef_to_tempids($restoreid, $inforeffile); // Load each inforef file to temp_ids
}
// If restoring users, check we are able to create all them
if ($restoreusers) {
$file = $controller->get_plan()->get_basepath() . '/users.xml';
$restoreid = $controller->get_restoreid();
$courseid = $controller->get_courseid();
$userid = $controller->get_userid();
$inforeffiles = restore_dbops::get_needed_inforef_files($restoreid); // Get all inforef files
foreach ($inforeffiles as $inforeffile) {
restore_dbops::load_inforef_to_tempids($restoreid, $inforeffile); // Load each inforef file to temp_ids
}
restore_dbops::load_users_to_tempids($restoreid, $file); // Load needed users to temp_ids
if ($problems = restore_dbops::precheck_included_users($restoreid, $courseid, $userid, $samesite)) {
$errors = array_merge($errors, $problems);
@@ -108,7 +112,13 @@ abstract class restore_prechecks_helper {
}
// TODO: Perform role_mappings, warning about non-mappable ones being ignored (see 1.9)
// (restore won't create roles in any case)
// Note: restore won't create roles at all. Only mapping/skip!
$file = $controller->get_plan()->get_basepath() . '/roles.xml';
restore_dbops::load_roles_to_tempids($restoreid, $file); // Load needed users to temp_ids
if ($problems = restore_dbops::precheck_included_roles($restoreid, $courseid, $userid, $samesite)) {
$errors = array_key_exists('errors', $problems) ? array_merge($errors, $problems['errors']) : $errors;
$warnings = array_key_exists('warnings', $problems) ? array_merge($warnings, $problems['warnings']) : $warnings;
}
// Prepare results and return
$results = array();
@@ -38,6 +38,7 @@ require_once($CFG->dirroot . '/backup/util/helper/restore_prechecks_helper.class
require_once($CFG->dirroot . '/backup/util/helper/restore_moodlexml_parser_processor.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_inforef_parser_processor.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_users_parser_processor.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_roles_parser_processor.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_structure_parser_processor.class.php');
require_once($CFG->dirroot . '/backup/util/xml/parser/progressive_parser.class.php');
require_once($CFG->dirroot . '/backup/util/output/output_controller.class.php');