Ejemplo n.º 1
0
 /**
  * What to do when this step is executed.
  */
 protected function define_execution()
 {
     global $DB;
     $this->log('processing file aliases queue', backup::LOG_DEBUG);
     $fs = get_file_storage();
     // Load the queue.
     $rs = $DB->get_recordset('backup_ids_temp', array('backupid' => $this->get_restoreid(), 'itemname' => 'file_aliases_queue'), '', 'info');
     // Iterate over aliases in the queue.
     foreach ($rs as $record) {
         $info = backup_controller_dbops::decode_backup_temp_info($record->info);
         // Try to pick a repository instance that should serve the alias.
         $repository = $this->choose_repository($info);
         if (is_null($repository)) {
             $this->notify_failure($info, 'unable to find a matching repository instance');
             continue;
         }
         if ($info->oldfile->repositorytype === 'local' or $info->oldfile->repositorytype === 'coursefiles') {
             // Aliases to Server files and Legacy course files may refer to a file
             // contained in the backup file or to some existing file (if we are on the
             // same site).
             try {
                 $reference = file_storage::unpack_reference($info->oldfile->reference);
             } catch (Exception $e) {
                 $this->notify_failure($info, 'invalid reference field format');
                 continue;
             }
             // Let's see if the referred source file was also included in the backup.
             $candidates = $DB->get_recordset('backup_files_temp', array('backupid' => $this->get_restoreid(), 'contextid' => $reference['contextid'], 'component' => $reference['component'], 'filearea' => $reference['filearea'], 'itemid' => $reference['itemid']), '', 'info, newcontextid, newitemid');
             $source = null;
             foreach ($candidates as $candidate) {
                 $candidateinfo = backup_controller_dbops::decode_backup_temp_info($candidate->info);
                 if ($candidateinfo->filename === $reference['filename'] and $candidateinfo->filepath === $reference['filepath'] and !is_null($candidate->newcontextid) and !is_null($candidate->newitemid)) {
                     $source = $candidateinfo;
                     $source->contextid = $candidate->newcontextid;
                     $source->itemid = $candidate->newitemid;
                     break;
                 }
             }
             $candidates->close();
             if ($source) {
                 // We have an alias that refers to another file also included in
                 // the backup. Let us change the reference field so that it refers
                 // to the restored copy of the original file.
                 $reference = file_storage::pack_reference($source);
                 // Send the new alias to the filepool.
                 $fs->create_file_from_reference($info->newfile, $repository->id, $reference);
                 $this->notify_success($info);
                 continue;
             } else {
                 // This is a reference to some moodle file that was not contained in the backup
                 // file. If we are restoring to the same site, keep the reference untouched
                 // and restore the alias as is if the referenced file exists.
                 if ($this->task->is_samesite()) {
                     if ($fs->file_exists($reference['contextid'], $reference['component'], $reference['filearea'], $reference['itemid'], $reference['filepath'], $reference['filename'])) {
                         $reference = file_storage::pack_reference($reference);
                         $fs->create_file_from_reference($info->newfile, $repository->id, $reference);
                         $this->notify_success($info);
                         continue;
                     } else {
                         $this->notify_failure($info, 'referenced file not found');
                         continue;
                     }
                     // If we are at other site, we can't restore this alias.
                 } else {
                     $this->notify_failure($info, 'referenced file not included');
                     continue;
                 }
             }
         } else {
             if ($info->oldfile->repositorytype === 'user') {
                 if ($this->task->is_samesite()) {
                     // For aliases to user Private files at the same site, we have a chance to check
                     // if the referenced file still exists.
                     try {
                         $reference = file_storage::unpack_reference($info->oldfile->reference);
                     } catch (Exception $e) {
                         $this->notify_failure($info, 'invalid reference field format');
                         continue;
                     }
                     if ($fs->file_exists($reference['contextid'], $reference['component'], $reference['filearea'], $reference['itemid'], $reference['filepath'], $reference['filename'])) {
                         $reference = file_storage::pack_reference($reference);
                         $fs->create_file_from_reference($info->newfile, $repository->id, $reference);
                         $this->notify_success($info);
                         continue;
                     } else {
                         $this->notify_failure($info, 'referenced file not found');
                         continue;
                     }
                     // If we are at other site, we can't restore this alias.
                 } else {
                     $this->notify_failure($info, 'restoring at another site');
                     continue;
                 }
             } else {
                 // This is a reference to some external file such as in boxnet or dropbox.
                 // If we are restoring to the same site, keep the reference untouched and
                 // restore the alias as is.
                 if ($this->task->is_samesite()) {
                     $fs->create_file_from_reference($info->newfile, $repository->id, $info->oldfile->reference);
                     $this->notify_success($info);
                     continue;
                     // If we are at other site, we can't restore this alias.
                 } else {
                     $this->notify_failure($info, 'restoring at another site');
                     continue;
                 }
             }
         }
     }
     $rs->close();
 }
Ejemplo n.º 2
0
 /**
  * For the target course context, put as many custom role names as possible
  */
 public static function set_course_role_names($restoreid, $courseid)
 {
     global $DB;
     // Get the course context
     $coursectx = context_course::instance($courseid);
     // Get all the mapped roles we have
     $rs = $DB->get_recordset('backup_ids_temp', array('backupid' => $restoreid, 'itemname' => 'role'), '', 'itemid, info, newitemid');
     foreach ($rs as $recrole) {
         $info = backup_controller_dbops::decode_backup_temp_info($recrole->info);
         // If it's one mapped role and we have one name for it
         if (!empty($recrole->newitemid) && !empty($info['nameincourse'])) {
             // If role name doesn't exist, add it
             $rolename = new stdclass();
             $rolename->roleid = $recrole->newitemid;
             $rolename->contextid = $coursectx->id;
             if (!$DB->record_exists('role_names', (array) $rolename)) {
                 $rolename->name = $info['nameincourse'];
                 $DB->insert_record('role_names', $rolename);
             }
         }
     }
     $rs->close();
 }
 function test_backup_controller_dbops()
 {
     global $DB;
     $dbman = $DB->get_manager();
     // Going to use some database_manager services for testing
     // Instantiate non interactive backup_controller
     $bc = new mock_backup_controller4dbops(backup::TYPE_1ACTIVITY, $this->moduleid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $this->userid);
     $this->assertTrue($bc instanceof backup_controller);
     // Calculate checksum
     $checksum = $bc->calculate_checksum();
     $this->assertEquals(strlen($checksum), 32);
     // is one md5
     // save controller
     $recid = backup_controller_dbops::save_controller($bc, $checksum);
     $this->assertNotEmpty($recid);
     // save it again (should cause update to happen)
     $recid2 = backup_controller_dbops::save_controller($bc, $checksum);
     $this->assertNotEmpty($recid2);
     $this->assertEquals($recid, $recid2);
     // Same record in both save operations
     // Try incorrect checksum
     $bc = new mock_backup_controller4dbops(backup::TYPE_1ACTIVITY, $this->moduleid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $this->userid);
     $checksum = $bc->calculate_checksum();
     try {
         $recid = backup_controller_dbops::save_controller($bc, 'lalala');
         $this->assertTrue(false, 'backup_dbops_exception expected');
     } catch (exception $e) {
         $this->assertTrue($e instanceof backup_dbops_exception);
         $this->assertEquals($e->errorcode, 'backup_controller_dbops_saving_checksum_mismatch');
     }
     // Try to save non backup_controller object
     $bc = new stdclass();
     try {
         $recid = backup_controller_dbops::save_controller($bc, 'lalala');
         $this->assertTrue(false, 'backup_controller_exception expected');
     } catch (exception $e) {
         $this->assertTrue($e instanceof backup_controller_exception);
         $this->assertEquals($e->errorcode, 'backup_controller_expected');
     }
     // save and load controller (by backupid). Then compare
     $bc = new mock_backup_controller4dbops(backup::TYPE_1ACTIVITY, $this->moduleid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $this->userid);
     $checksum = $bc->calculate_checksum();
     // Calculate checksum
     $backupid = $bc->get_backupid();
     $this->assertEquals(strlen($backupid), 32);
     // is one md5
     $recid = backup_controller_dbops::save_controller($bc, $checksum);
     // save controller
     $newbc = backup_controller_dbops::load_controller($backupid);
     // load controller
     $this->assertTrue($newbc instanceof backup_controller);
     $newchecksum = $newbc->calculate_checksum();
     $this->assertEquals($newchecksum, $checksum);
     // try to load non-existing controller
     try {
         $bc = backup_controller_dbops::load_controller('1234567890');
         $this->assertTrue(false, 'backup_dbops_exception expected');
     } catch (exception $e) {
         $this->assertTrue($e instanceof backup_dbops_exception);
         $this->assertEquals($e->errorcode, 'backup_controller_dbops_nonexisting');
     }
     // backup_ids_temp table tests
     // If, for any reason table exists, drop it
     if ($dbman->table_exists('backup_ids_temp')) {
         $dbman->drop_table(new xmldb_table('backup_ids_temp'));
     }
     // Check backup_ids_temp table doesn't exist
     $this->assertFalse($dbman->table_exists('backup_ids_temp'));
     // Create and check it exists
     backup_controller_dbops::create_backup_ids_temp_table('testingid');
     $this->assertTrue($dbman->table_exists('backup_ids_temp'));
     // Drop and check it doesn't exists anymore
     backup_controller_dbops::drop_backup_ids_temp_table('testingid');
     $this->assertFalse($dbman->table_exists('backup_ids_temp'));
     // Test encoding/decoding of backup_ids_temp,backup_files_temp encode/decode functions.
     // We need to handle both objects and data elements.
     $object = new stdClass();
     $object->item1 = 10;
     $object->item2 = 'a String';
     $testarray = array($object, 10, null, 'string', array('a' => 'b', 1 => 1));
     foreach ($testarray as $item) {
         $encoded = backup_controller_dbops::encode_backup_temp_info($item);
         $decoded = backup_controller_dbops::decode_backup_temp_info($encoded);
         $this->assertEquals($item, $decoded);
     }
 }
 public function add_related_legacy_files($component, $filearea, $mappingitemname)
 {
     global $CFG, $DB;
     $results = array();
     $restoreid = $this->get_restoreid();
     $oldcontextid = $this->task->get_old_contextid();
     $component = 'mod_dialogue';
     $newfilearea = $filearea;
     if ($filearea == 'entry') {
         $newfilearea = 'message';
     }
     if ($filearea == 'attachment') {
         $newfilearea = 'attachment';
     }
     // Get new context, must exist or this will fail
     if (!($newcontextid = restore_dbops::get_backup_ids_record($restoreid, 'context', $oldcontextid)->newitemid)) {
         throw new restore_dbops_exception('unknown_context_mapping', $oldcontextid);
     }
     $sql = "SELECT id AS bftid, contextid, component, filearea, itemid, itemid AS newitemid, info\n                      FROM {backup_files_temp}\n                     WHERE backupid = ?\n                       AND contextid = ?\n                       AND component = ?\n                       AND filearea  = ?";
     $params = array($restoreid, $oldcontextid, $component, $filearea);
     $fs = get_file_storage();
     // Get moodle file storage
     $basepath = $this->get_basepath() . '/files/';
     // Get backup file pool base
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach ($rs as $rec) {
         // get mapped id
         $rec->newitemid = $this->get_mappingid('dialogue_message', $rec->itemid);
         if (BACKUP::RELEASE >= '2.6') {
             // new line of code for 2.6 or breaks
             $file = (object) backup_controller_dbops::decode_backup_temp_info($rec->info);
         } else {
             $file = (object) unserialize(base64_decode($rec->info));
         }
         // ignore root dirs (they are created automatically)
         if ($file->filepath == '/' && $file->filename == '.') {
             continue;
         }
         // set the best possible user
         $mappeduser = restore_dbops::get_backup_ids_record($restoreid, 'user', $file->userid);
         $mappeduserid = !empty($mappeduser) ? $mappeduser->newitemid : $this->task->get_userid();
         // dir found (and not root one), let's create it
         if ($file->filename == '.') {
             $fs->create_directory($newcontextid, $component, $filearea, $rec->newitemid, $file->filepath, $mappeduserid);
             continue;
         }
         if (empty($file->repositoryid)) {
             // this is a regular file, it must be present in the backup pool
             $backuppath = $basepath . backup_file_manager::get_backup_content_file_location($file->contenthash);
             // The file is not found in the backup.
             if (!file_exists($backuppath)) {
                 $result = new stdClass();
                 $result->code = 'file_missing_in_backup';
                 $result->message = sprintf('missing file %s%s in backup', $file->filepath, $file->filename);
                 $result->level = backup::LOG_WARNING;
                 $results[] = $result;
                 continue;
             }
             // create the file in the filepool if it does not exist yet
             if (!$fs->file_exists($newcontextid, $component, $filearea, $rec->newitemid, $file->filepath, $file->filename)) {
                 // If no license found, use default.
                 if ($file->license == null) {
                     $file->license = $CFG->sitedefaultlicense;
                 }
                 $file_record = array('contextid' => $newcontextid, 'component' => $component, 'filearea' => $newfilearea, 'itemid' => $rec->newitemid, 'filepath' => $file->filepath, 'filename' => $file->filename, 'timecreated' => $file->timecreated, 'timemodified' => $file->timemodified, 'userid' => $mappeduserid, 'author' => $file->author, 'license' => $file->license, 'sortorder' => $file->sortorder);
                 $fs->create_file_from_pathname($file_record, $backuppath);
             }
             // store the the new contextid and the new itemid in case we need to remap
             // references to this file later
             $DB->update_record('backup_files_temp', array('id' => $rec->bftid, 'newcontextid' => $newcontextid, 'newitemid' => $rec->newitemid), true);
         } else {
             // this is an alias - we can't create it yet so we stash it in a temp
             // table and will let the final task to deal with it
             if (!$fs->file_exists($newcontextid, $component, $filearea, $rec->newitemid, $file->filepath, $file->filename)) {
                 $info = new stdClass();
                 // oldfile holds the raw information stored in MBZ (including reference-related info)
                 $info->oldfile = $file;
                 // newfile holds the info for the new file_record with the context, user and itemid mapped
                 $info->newfile = (object) array('contextid' => $newcontextid, 'component' => $component, 'filearea' => $newfilearea, 'itemid' => $rec->newitemid, 'filepath' => $file->filepath, 'filename' => $file->filename, 'timecreated' => $file->timecreated, 'timemodified' => $file->timemodified, 'userid' => $mappeduserid, 'author' => $file->author, 'license' => $file->license, 'sortorder' => $file->sortorder);
                 restore_dbops::set_backup_ids_record($restoreid, 'file_aliases_queue', $file->id, 0, null, $info);
             }
         }
     }
     $rs->close();
     return $results;
 }