class restore_create_and_clean_temp_stuff extends restore_execution_step {
protected function define_execution() {
- $exists = restore_controller_dbops::create_backup_ids_temp_table($this->get_restoreid()); // Create temp table conditionally
+ $exists = restore_controller_dbops::create_restore_temp_tables($this->get_restoreid()); // temp tables conditionally
// If the table already exists, it's because restore_prechecks have been executed in the same
// request (without problems) and it already contains a bunch of preloaded information (users...)
// that we aren't going to execute again
protected function define_execution() {
global $CFG;
- backup_controller_dbops::drop_backup_ids_temp_table($this->get_restoreid()); // Drop ids temp table
+ restore_controller_dbops::drop_restore_temp_tables($this->get_restoreid()); // Drop ids temp table
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60)); // Delete > 4 hours temp dirs
if (empty($CFG->keeptempdirectoriesonbackup)) { // Conditionally
backup_helper::delete_backup_dir($this->get_restoreid()); // Empty backup dir
}
/*
- * Execution step that will load all the needed files into backup_temp_ids.
- * - itemname: contains "file*component*fileara"
- * - itemid: contains the original id of the file
- * - newitemid: contains the itemid of the file
- * - parentitemid: contains the context of the file
+ * Execution step that will load all the needed files into backup_files_temp
* - info: contains the whole original object (times, names...)
* (all them being original ids as loaded from xml)
*/
$data = (object)$data; // handy
- $itemname = 'file*' . $data->component . '*' . $data->filearea;
- $itemid = $data->id;
- $newitemid = $data->itemid;
- $parentitemid = $data->contextid;
- $info = $data;
-
// 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
- $isfileref = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'fileref', $itemid);
+ $isfileref = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'fileref', $data->id);
$iscomponent = ($data->component == 'user' || $data->component == 'group' || $data->component == 'grade');
if ($isfileref || $iscomponent) {
- restore_dbops::set_backup_ids_record($this->get_restoreid(), $itemname, $itemid, $newitemid, $parentitemid, $info);
+ restore_dbops::set_backup_files_record($this->get_restoreid(), $data);
}
}
}
}
protected function after_execute() {
- return;
+ // Add group related files, matching with "group" mappings
$this->add_related_files('group', 'icon', 'group');
$this->add_related_files('group', 'description', 'group');
- restore_dbops::send_files_to_pool($basepath, $restoreid, 'user', 'private', $recuser->parentitemid);
}
}
}
public static function create_backup_ids_temp_table($backupid) {
+ self::create_temptable_from_real_table($backupid, 'backup_ids_template', 'backup_ids_temp');
+ }
+
+ /**
+ * Given one "real" tablename, create one temp table suitable for be used in backup/restore operations
+ */
+ public static function create_temptable_from_real_table($backupid, $realtablename, $temptablename) {
global $CFG, $DB;
$dbman = $DB->get_manager(); // We are going to use database_manager services
- // Note: For now we are going to load the backup_ids_template from core lib/db/install.xml
+ // Note: For now we are going to load the realtablename from core lib/db/install.xml
// that way, any change in the "template" will be applied here automatically. If this causes
// too much slow, we can always forget about the template and keep maintained the xmldb_table
// structure inline - manually - here.
- $templatetablename = 'backup_ids_template';
- $targettablename = 'backup_ids_temp';
- $xmldb_file = new xmldb_file($CFG->dirroot . '/lib/db/install.xml');
+ $templatetablename = $realtablename;
+ $targettablename = $temptablename;
+ $xmlfile = $CFG->dirroot . '/lib/db/install.xml';
+ $xmldb_file = new xmldb_file($xmlfile);
if (!$xmldb_file->fileExists()) {
throw new ddl_exception('ddlxmlfileerror', null, 'File does not exist');
}
$xmldb_structure = $xmldb_file->getStructure();
$xmldb_table = $xmldb_structure->getTable($templatetablename);
if (is_null($xmldb_table)) {
- throw new ddl_exception('ddlunknowntable', null, 'The table ' . $templatetablename . ' is not defined in file ' . $file);
+ throw new ddl_exception('ddlunknowntable', null, 'The table ' . $templatetablename . ' is not defined in file ' . $xmlfile);
}
// Set default backupid (not needed but this enforce any missing backupid). That's hackery in action!
$xmldb_table->getField('backupid')->setDefault($backupid);
return $controller;
}
- public static function create_backup_ids_temp_table($restoreid) {
+ public static function create_restore_temp_tables($restoreid) {
global $CFG, $DB;
$dbman = $DB->get_manager(); // We are going to use database_manager services
// TODO: If not match, exception, table corresponds to another backup/restore operation
return true;
}
- backup_controller_dbops::create_backup_ids_temp_table($restoreid); // Create ids temp table
+ backup_controller_dbops::create_temptable_from_real_table($restoreid, 'backup_ids_template', 'backup_ids_temp');
+ backup_controller_dbops::create_temptable_from_real_table($restoreid, 'backup_files_template', 'backup_files_temp');
return false;
}
+
+ public static function drop_restore_temp_tables($backupid) {
+ global $DB;
+ $dbman = $DB->get_manager(); // We are going to use database_manager services
+
+ $targettablenames = array('backup_ids_temp', 'backup_files_temp');
+ foreach ($targettablenames as $targettablename) {
+ $table = new xmldb_table($targettablename);
+ $dbman->drop_temp_table($table); // And drop it
+ }
+ }
}
}
// Important: remember how files have been loaded to backup_ids_temp
- // - itemname: contains "file*component*fileara"
- // - itemid: contains the original id of the file
- // - newitemid: contains the itemid of the file
- // - parentitemid: contains the context of the file
// - info: contains the whole original object (times, names...)
// (all them being original ids as loaded from xml)
// itemname = null, we are going to match only by context, no need to use itemid (all them are 0)
if ($itemname == null) {
- $sql = 'SELECT id, itemname, itemid, 0 AS newitemid
- FROM {backup_ids_temp}
+ $sql = 'SELECT contextid, component, filearea, itemid, 0 AS newitemid, info
+ FROM {backup_files_temp}
WHERE backupid = ?
- AND itemname = ?
- AND parentitemid = ?';
- $params = array($restoreid, 'file*' . $component . '*' . $filearea, $oldcontextid);
+ AND contextid = ?
+ AND component = ?
+ AND filearea = ?';
+ $params = array($restoreid, $oldcontextid, $component, $filearea);
- // itemname not null, going to join by context and itemid, we'll need itemid (non zero)
+ // itemname not null, going to join with backup_ids to perform the old-new mapping of itemids
} else {
- $sql = 'SELECT f.id, f.itemname, f.itemid, i.newitemid
- FROM {backup_ids_temp} f
+ $sql = 'SELECT f.contextid, f.component, f.filearea, f.itemid, i.newitemid, f.info
+ FROM {backup_files_temp} f
JOIN {backup_ids_temp} i ON i.backupid = f.backupid
- AND i.parentitemid = f.parentitemid
- AND i.itemid = f.newitemid
+ AND i.parentitemid = f.contextid
+ AND i.itemid = f.itemid
WHERE f.backupid = ?
- AND f.itemname = ?
- AND f.parentitemid = ?
+ AND f.contextid = ?
+ AND f.component = ?
+ AND f.filearea = ?
AND i.itemname = ?';
- $params = array($restoreid, 'file*' . $component . '*' . $filearea, $oldcontextid, $itemname);
+ $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
foreach ($rs as $rec) {
- $file = (object)self::get_backup_ids_record($restoreid, $rec->itemname, $rec->itemid)->info;
+ $file = (object)unserialize(base64_decode($rec->info));
// ignore root dirs (they are created automatically)
if ($file->filepath == '/' && $file->filename == '.') {
continue;
}
}
+ public static function set_backup_files_record($restoreid, $filerec) {
+ global $DB;
+
+ $filerec->info = base64_encode(serialize($filerec)); // Serialize the whole rec in info
+ $filerec->backupid = $restoreid;
+ $DB->insert_record('backup_files_temp', $filerec);
+ }
+
public static function set_backup_ids_record($restoreid, $itemname, $itemid, $newitemid = 0, $parentitemid = null, $info = null) {
global $DB;
/**
* Add all the existing file, given their component and filearea and one backup_ids itemname to match with
*/
- protected function add_related_files($componentname, $filearea, $mappingitemname) {
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $componentname,
+ protected function add_related_files($component, $filearea, $mappingitemname) {
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component,
$filearea, $this->task->get_old_contextid(), $mappingitemname);
}