/** * This function, executed after all the tasks in the plan * have been executed, will perform the recode of the * target activity for the block. This must be done here * and not in normal execution so we are sure everything is * at its finale place. */ public function after_restore() { global $DB; // Get the blockid. $blockid = $this->get_blockid(); if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); if (!empty($config->section_id)) { // Get the mapping and replace it in config. if ($mapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_section', $config->section_id)) { // Update the parent module id (the id from mdl_quiz etc...) $config->section_id = $mapping->newitemid; // Encode and save the config. $configdata = base64_encode(serialize($config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid)); // Arrange the replace link in the course_sections summary. $newsection = $DB->get_record('course_sections', array('id' => $mapping->newitemid)); // Update the Side Bar section with the required values to make it work. $reseturl = new moodle_url('/blocks/side_bar/reset.php?cid=' . $newsection->course); $newsection->name = get_string('sidebar', 'block_side_bar'); $newsection->summary = get_string('sectionsummary', 'block_side_bar', (string) html_writer::link($reseturl, $reseturl)); $newsection->summaryformat = FORMAT_HTML; $newsection->visible = true; $DB->update_record('course_sections', $newsection); } } } }
protected function dispatch_chunk($data) { // Prepare question_category record if ($data['path'] == '/question_categories/question_category') { $info = (object) $data['tags']; $itemname = 'question_category'; $itemid = $info->id; $parentitemid = $info->contextid; $this->lastcatid = $itemid; // Prepare question record } else { if ($data['path'] == '/question_categories/question_category/questions/question') { $info = (object) $data['tags']; $itemname = 'question'; $itemid = $info->id; $parentitemid = $this->lastcatid; // Not question_category nor question, impossible. Throw exception. } else { throw new progressive_parser_exception('restore_questions_parser_processor_unexpected_path', $data['path']); } } // Only load it if needed (exist same question_categoryref itemid in table) if (restore_dbops::get_backup_ids_record($this->restoreid, 'question_categoryref', $this->lastcatid)) { restore_dbops::set_backup_ids_record($this->restoreid, $itemname, $itemid, 0, $parentitemid, $info); } }
public function after_restore() { global $DB; $course_id = $this->get_courseid(); $records = $DB->get_records("block_lockdownbrowser_sett", array("course" => $course_id)); if ($records === FALSE) { return; } $missing_ids = 0; foreach ($records as $settings) { $old_quizid = $settings->quizid; if (empty($old_quizid)) { continue; } $quizmap = restore_dbops::get_backup_ids_record($this->get_restoreid(), "quiz", $old_quizid); if (empty($quizmap)) { $missing_ids++; continue; } $settings->quizid = $quizmap->newitemid; $DB->update_record('block_lockdownbrowser_sett', $settings); } if ($missing_ids > 0) { $this->get_logger()->process("Failed to restore dependency in block 'lockdownbrowser'. " . "Backup and restore will not work correctly unless you " . "include the dependent 'quiz' modules.", backup::LOG_ERROR); } }
/** * This function, executed after all the tasks in the plan * have been executed, will perform the recode of the * target glossary for the block. This must be done here * and not in normal execution steps because the glossary * may be restored after the block. */ public function after_restore() { global $DB; // Get the blockid $blockid = $this->get_blockid(); // Extract block configdata and update it to point to the new glossary if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); if (!empty($config->glossary)) { if ($glossarymap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary', $config->glossary)) { // Get glossary mapping and replace it in config $config->glossary = $glossarymap->newitemid; } else { if ($this->is_samesite()) { // We are restoring on the same site, check if glossary can be used in the block in this course. $glossaryid = $DB->get_field_sql("SELECT id FROM {glossary} " . "WHERE id = ? AND (course = ? OR globalglossary = 1)", [$config->glossary, $this->get_courseid()]); if (!$glossaryid) { unset($config->glossary); } } else { // The block refers to a glossary not present in the backup file. unset($config->glossary); } } // Unset config variables that are no longer used. unset($config->globalglossary); unset($config->courseid); // Save updated config. $configdata = base64_encode(serialize($config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid)); } } }
/** * This function, executed after all the tasks in the plan * have been executed, will perform the recode of the * target quiz for the block. This must be done here * and not in normal execution steps because the quiz * can be restored after the block. */ public function after_restore() { global $DB; // Get the blockid. $blockid = $this->get_blockid(); // Extract block configdata and update it to point to the new quiz. if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); if (!empty($config->quizid)) { // Get quiz mapping and replace it in config. if ($quizmap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'quiz', $config->quizid)) { $config->activityparent = 'quiz'; $config->activityparentid = $quizmap->newitemid; // Set the decimal valuue as appropriate. if ($config->gradeformat == 1) { // This block is using percentages, do not display any decimal places. $config->decimalpoints = 0; } else { // Get the decimal value from the corresponding quiz. $config->decimalpoints = $DB->get_field('quiz', 'decimalpoints', array('id' => $config->activityparentid)); } // Get the grade_items record to set the activitygradeitemid. $info = $DB->get_record('grade_items', array('iteminstance' => $config->activityparentid, 'itemmodule' => $config->activityparent)); $config->activitygradeitemid = $info->id; unset($config->quizid); // Save the new configuration and update the record. $DB->set_field('block_instances', 'configdata', base64_encode(serialize($config)), array('id' => $blockid)); $DB->set_field('block_instances', 'blockname', 'activity_results', array('id' => $blockid)); } } } }
/** * This function, executed after all the tasks in the plan * have been executed, will remove tag collection reference in case block was restored into another site. * Also get mapping of contextid. */ public function after_restore() { global $DB; // Get the blockid. $blockid = $this->get_blockid(); // Extract block configdata and remove tag collection reference if this is another site. Also map contextid. if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); $changed = false; if (!empty($config->tagcoll) && $config->tagcoll > 1 && !$this->is_samesite()) { $config->tagcoll = 0; $changed = true; } if (!empty($config->ctx)) { if ($ctxmap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'context', $config->ctx)) { $config->ctx = $ctxmap->newitemid; } else { $config->ctx = 0; } $changed = true; } if ($changed) { $configdata = base64_encode(serialize($config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid)); } } }
protected function dispatch_chunk($data) { // Received one role chunck, we are going to store it into backup_ids // table, with name = role $itemname = 'role'; $itemid = $data['tags']['id']; $info = $data['tags']; // Only load it if needed (exist same roleref itemid in table) if (restore_dbops::get_backup_ids_record($this->restoreid, 'roleref', $itemid)) { restore_dbops::set_backup_ids_record($this->restoreid, $itemname, $itemid, 0, null, $info); } }
protected function dispatch_chunk($data) { // Received one user chunck, we are going to store it into backup_ids // table, with name = user and parentid = contextid for later use $itemname = 'user'; $itemid = $data['tags']['id']; $parentitemid = $data['tags']['contextid']; $info = $data['tags']; // Only load it if needed (exist same userref itemid in table) if (restore_dbops::get_backup_ids_record($this->restoreid, 'userref', $itemid)) { restore_dbops::set_backup_ids_record($this->restoreid, $itemname, $itemid, 0, $parentitemid, $info); } }
/** * Checks if mapped questions are exact valid, or marks them to be created * * @global $DB * @throws moodle_exception */ protected function define_execution() { global $DB; $restoreid = $this->get_restoreid(); $courseid = $this->get_courseid(); $userid = $this->task->get_userid(); $workaround_qtypes = explode(',', get_config('block_sharing_cart', 'workaround_qtypes')); // @see /backup/util/dbops/restore_dbops.class.php#prechek_precheck_qbanks_by_level $contexts = restore_dbops::restore_get_question_banks($restoreid); foreach ($contexts as $contextid => $contextlevel) { $categories = restore_dbops::restore_get_question_categories($restoreid, $contextid); $canadd = false; if ($targetcontext = restore_dbops::restore_find_best_target_context($categories, $courseid, $contextlevel)) { $canadd = has_capability('moodle/question:add', $targetcontext, $userid); } foreach ($categories as $category) { $questions = restore_dbops::restore_get_questions($restoreid, $category->id); foreach ($questions as $question) { if (!in_array($question->qtype, $workaround_qtypes)) { continue; } $mapping = restore_dbops::get_backup_ids_record($restoreid, 'question', $question->id); if ($mapping && $mapping->newitemid && !self::is_question_valid($question->qtype, $mapping->newitemid)) { if (!$canadd) { throw new moodle_exception('questioncannotberestored', 'backup', '', $question); } $catmapping = restore_dbops::get_backup_ids_record($restoreid, 'question_category', $category->id); $matchquestions = $DB->get_records('question', array('category' => $catmapping->newitemid, 'qtype' => $question->qtype, 'stamp' => $question->stamp, 'version' => $question->version)); $newitemid = 0; // to be created if no valid duplicate exists foreach ($matchquestions as $q) { if ($q->id == $mapping->newitemid) { continue; } if (self::is_question_valid($question->qtype, $q->id)) { $newitemid = $q->id; // updates mapping if a valid one found break; } } $this->update_mapping($mapping, $newitemid); } } } } }
/** * This function, executed after all the tasks in the plan * have been executed, will perform the recode of the * target quiz for the block. This must be done here * and not in normal execution steps because the quiz * can be restored after the block. */ public function after_restore() { global $DB; // Get the blockid $blockid = $this->get_blockid(); // Extract block configdata and update it to point to the new quiz if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); if (!empty($config->quizid)) { // Get quiz mapping and replace it in config if ($quizmap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'quiz', $config->quizid)) { $config->quizid = $quizmap->newitemid; $configdata = base64_encode(serialize($config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid)); } } } }
public function after_restore() { global $DB; // Find all the items that have a 'moduleid' but are not headings and match them up to the newly-restored activities. $items = $DB->get_records_select('checklist_item', 'checklist = ? AND moduleid > 0 AND itemoptional <> 2', array($this->get_activityid())); foreach ($items as $item) { $moduleid = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $item->moduleid); if ($moduleid) { // Match up the moduleid to the restored activity module. $DB->set_field('checklist_item', 'moduleid', $moduleid->newitemid, array('id' => $item->id)); } else { // Does not match up to a restored activity module => delete the item + associated user data. $DB->delete_records('checklist_check', array('item' => $item->id)); $DB->delete_records('checklist_comment', array('itemid' => $item->id)); $DB->delete_records('checklist_item', array('id' => $item->id)); } } }
/** * Translates the backed up configuration data for the target course modules. * * @global type $DB */ public function after_restore() { global $DB; $prefixes = array('monitor_', 'date_time_', 'action_', 'locked_'); // Get the blockid. $id = $this->get_blockid(); // Get restored course id. $courseid = $this->get_courseid(); if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $id))) { $config = (array) unserialize(base64_decode($configdata)); $newconfig = $config; // Filter module related config information. foreach ($newconfig as $key => $value) { foreach ($prefixes as $prefix) { if (substr($key, 0, strlen($prefix)) === $prefix) { unset($newconfig[$key]); } } } // Translate the old config information to the target course values. foreach ($config as $key => $value) { $matches = array(); preg_match('/monitor_(\\D+)(\\d+)/', $key, $matches); if (!empty($matches)) { $module = $matches[1]; $instance = $matches[2]; // Find the mapped instance ID. if ($newinstance = restore_dbops::get_backup_ids_record($this->get_restoreid(), $module, $instance)) { $newinstanceid = $newinstance->newitemid; // Translate new instance values from old IDs. foreach ($prefixes as $prefix) { if (isset($config["{$prefix}{$module}{$instance}"])) { $newconfig["{$prefix}{$module}{$newinstanceid}"] = $config["{$prefix}{$module}{$instance}"]; } } } } } // Save everything back to DB. $configdata = base64_encode(serialize((object) $newconfig)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $id)); } }
/** * Translates the backed up configuration data for the target course modules * * @global type $DB */ public function after_restore() { global $DB; // Get the blockid $id = $this->get_blockid(); //Restored course id $courseid = $this->get_courseid(); if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $id))) { $config = (array) unserialize(base64_decode($configdata)); // Translate the old config information to the target course values foreach ($config as $key => $value) { $matches = array(); preg_match('/monitor_(\\D+)(\\d+)/', $key, $matches); if ($value == 1 && !empty($matches)) { $module = $matches[1]; $instance = $matches[2]; // Find a matching module in the target course if ($cm = get_coursemodule_from_instance($module, $instance)) { // Get new cm and instance $newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), "course_module", $cm->id); $newcm = get_coursemodule_from_id($module, $newitem->newitemid); $newinstance = $newcm->instance; // Set new config $config["monitor_{$module}{$newinstance}"] = $config["monitor_{$module}{$instance}"]; $config["locked_{$module}{$newinstance}"] = $config["locked_{$module}{$instance}"]; $config["date_time_{$module}{$newinstance}"] = $config["date_time_{$module}{$instance}"]; $config["action_{$module}{$newinstance}"] = $config["action_{$module}{$instance}"]; // Unset old config unset($config["monitor_{$module}{$instance}"]); unset($config["locked_{$module}{$instance}"]); unset($config["date_time_{$module}{$instance}"]); unset($config["action_{$module}{$instance}"]); } } } // Save everything back to DB $configdata = base64_encode(serialize((object) $config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $id)); } }
public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) { global $DB; if (!$this->roleid) { // If using 'same as activity' option, no need to change it. return false; } $rec = \restore_dbops::get_backup_ids_record($restoreid, 'role', $this->roleid); if (!$rec || !$rec->newitemid) { // If we are on the same course (e.g. duplicate) then we can just // use the existing one. if ($DB->record_exists('roles', array('id' => $this->roleid, 'courseid' => $courseid))) { return false; } // Otherwise it's a warning. $this->roleid = -1; $logger->process('Restored item (' . $name . ') has availability condition on grouping that was not restored', \backup::LOG_WARNING); } else { $this->roleid = (int) $rec->newitemid; } return true; }
/** * This function, executed after all the tasks in the plan * have been executed, will perform the recode of the * target activity for the block. This must be done here * and not in normal execution steps because the activity * can be restored after the block. */ public function after_restore() { global $DB; // Get the blockid. $blockid = $this->get_blockid(); if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); if (!empty($config->activityparentid)) { // Get the mapping and replace it in config. if ($mapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), $config->activityparent, $config->activityparentid)) { // Update the parent module id (the id from mdl_quiz etc...) $config->activityparentid = $mapping->newitemid; // Get the grade_items record to update the activitygradeitemid. $info = $DB->get_record('grade_items', array('iteminstance' => $config->activityparentid, 'itemmodule' => $config->activityparent)); // Update the activitygradeitemid the id from the grade_items table. $config->activitygradeitemid = $info->id; // Encode and save the config. $configdata = base64_encode(serialize($config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid)); } } } }
/** * This function, executed after all the tasks in the plan * have been executed, will perform the recode of the * target glossary for the block. This must be done here * and not in normal execution steps because the glossary * may be restored after the block. */ public function after_restore() { global $DB; // Get the blockid $blockid = $this->get_blockid(); // Extract block configdata and update it to point to the new glossary if ($configdata = $DB->get_field('block_instances', 'configdata', array('id' => $blockid))) { $config = unserialize(base64_decode($configdata)); if (!empty($config->glossary)) { // Get glossary mapping and replace it in config if ($glossarymap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary', $config->glossary)) { $mappedglossary = $DB->get_record('glossary', array('id' => $glossarymap->newitemid), 'id,course,globalglossary', MUST_EXIST); $config->glossary = $mappedglossary->id; $config->courseid = $mappedglossary->course; $config->globalglossary = $mappedglossary->globalglossary; $configdata = base64_encode(serialize($config)); $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid)); } else { // The block refers to a glossary not present in the backup file. $DB->set_field('block_instances', 'configdata', '', array('id' => $blockid)); } } } }
protected function define_execution() { global $DB; // Let's process only created questions $questionsrs = $DB->get_recordset_sql("SELECT bi.itemid, bi.newitemid, bi.parentitemid, q.qtype FROM {backup_ids_temp} bi JOIN {question} q ON q.id = bi.newitemid WHERE bi.backupid = ? AND bi.itemname = 'question_created'", array($this->get_restoreid())); foreach ($questionsrs as $question) { // Get question_category mapping, it contains the target context for the question if (!$qcatmapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_category', $question->parentitemid)) { // Something went really wrong, cannot find the question_category for the question debugging('Error fetching target context for question', DEBUG_DEVELOPER); continue; } // Calculate source and target contexts $oldctxid = $qcatmapping->info->contextid; $newctxid = $qcatmapping->parentitemid; // Add common question files (question and question_answer ones) restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'questiontext', $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true); restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'generalfeedback', $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true); restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answer', $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true); restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback', $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true); restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint', $oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true); // Add qtype dependent files $components = backup_qtype_plugin::get_components_and_fileareas($question->qtype); foreach ($components as $component => $fileareas) { foreach ($fileareas as $filearea => $mapping) { // Use itemid only if mapping is question_created $itemid = ($mapping == 'question_created') ? $question->itemid : null; restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component, $filearea, $oldctxid, $this->task->get_userid(), $mapping, $itemid, $newctxid, true); } } } $questionsrs->close(); }
public function after_restore() { // Do something at end of restore. global $DB; // Get the blockid. $gameid = $this->get_activityid(); // Extract Game configdata and update it to point to the new glossary. $rec = $DB->get_record_select('game', 'id=' . $gameid, null, 'id,quizid,glossaryid,glossarycategoryid,questioncategoryid,bookid,glossaryid2,glossarycategoryid2'); $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'quiz', $rec->quizid); if ($ret != false) { $rec->quizid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary', $rec->glossaryid); if ($ret != false) { $rec->glossaryid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary_categories', $rec->glossarycategoryid); if ($ret != false) { $rec->glossarycategoryid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_categories', $rec->questioncategoryid); if ($ret != false) { $rec->questioncategoryid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book', $rec->bookid); if ($ret != false) { $rec->bookid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary', $rec->glossaryid2); if ($ret != false) { $rec->glossaryid2 = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary_categories', $rec->glossarycategoryid); if ($ret != false) { $rec->glossarycategoryid = $ret->newitemid; } $DB->update_record('game', $rec); // Read game_repetitions. $recs = $DB->get_records_select('game_repetitions', 'gameid=' . $gameid, null, '', 'id,questionid,glossaryentryid'); if ($recs != false) { foreach ($recs as $rec) { $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question', $rec->questionid); if ($ret != false) { $rec->questionid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary_entry', $rec->glossaryentryid); if ($ret != false) { $rec->glossaryentryid = $ret->newitemid; } $DB->update_record('game_repetitions', $rec); } } // Read game_queries. $recs = $DB->get_records_select('game_queries', 'gameid=' . $gameid, null, '', 'id,questionid,glossaryentryid,answerid'); if ($recs != false) { foreach ($recs as $rec) { $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question', $rec->questionid); if ($ret != false) { $rec->questionid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary_entry', $rec->glossaryentryid); if ($ret != false) { $rec->glossaryentryid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_answers', $rec->glossaryentryid); if ($ret != false) { $rec->answerid = $ret->newitemid; } $DB->update_record('game_queries', $rec); } } // Read bookquiz. $recs = $DB->get_records_select('game_bookquiz', 'id=' . $gameid, null, '', 'id,lastchapterid'); if ($recs != false) { foreach ($recs as $rec) { $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->lastchapterid); if ($ret != false) { $rec->lastchapterid = $ret->newitemid; } $DB->update_record('game_bookquiz', $rec); } } // Read bookquiz_chapters. $sql = "SELECT gbc.* " . "FROM {game_bookquiz_chapters} gbc LEFT JOIN {game_attempts} a ON gbc.attemptid = a.id" . " WHERE a.gameid={$gameid}"; $recs = $DB->get_records_sql($sql); if ($recs != false) { foreach ($recs as $rec) { $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->chapterid); if ($ret != false) { $rec->chapterid = $ret->newitemid; } $DB->update_record('game_bookquiz_chapter', $rec); } } // Read bookquiz_questions. $recs = $DB->get_records_select('game_bookquiz_questions', 'id=' . $gameid, null, '', 'id,chapterid,questioncategoryid'); if ($recs != false) { foreach ($recs as $rec) { $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->chapterid); if ($ret != false) { $rec->chapterid = $ret->newitemid; } $ret = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'book_chapters', $rec->questioncategoryid); if ($ret != false) { $rec->questioncategoryid = $ret->newitemid; } $DB->update_record('game_bookquiz_questions', $rec); } } }
/** * Restores a given stash stored previously by {@link self::set_stash()} * * @param string $stashname name of the stash * @param int $itemid optional id for multiple infos within the same stashname * @throws moodle1_convert_empty_storage_exception if the info has not been stashed previously * @return mixed stashed data */ public function get_stash($stashname, $itemid = 0) { $record = restore_dbops::get_backup_ids_record($this->get_id(), $stashname, $itemid); if (empty($record)) { throw new moodle1_convert_empty_storage_exception('required_not_stashed_data', array($stashname, $itemid)); } else { return $record->info; } }
protected function parse_tokens_and_matches($tokens, $values, $content) { $pairs = array_combine($tokens, $values); ksort($pairs); // First literals, then mappings foreach ($pairs as $token => $value) { // If one token has already been processed, continue if (array_key_exists($token, $this->allpairs)) { continue; } // If the pair is one literal token, just keep it unmodified if (substr($token, 0, 1) == '[') { $this->allpairs[$token] = $value; // If the pair is one mapping token, let's process it } else { if (substr($token, 0, 1) == '{') { $ctoken = $token; // First, resolve mappings to literals if necessary if (substr($token, 1, 1) == '[') { $literaltoken = trim($token, '{}'); if (array_key_exists($literaltoken, $this->allpairs)) { $ctoken = '{' . $this->allpairs[$literaltoken] . '}'; } } // Look for mapping in fixedvalues before going to DB $plaintoken = trim($ctoken, '{}'); if (array_key_exists($plaintoken, $this->fixedvalues)) { $this->allpairs[$token] = $this->fixedvalues[$plaintoken]; // Last chance, fetch value from backup_ids_temp, via mapping } else { if ($mapping = restore_dbops::get_backup_ids_record($this->restoreid, $plaintoken, $value)) { $this->allpairs[$token] = $mapping->newitemid; } } } } } // Apply all the conversions array (allpairs) to content krsort($this->allpairs); // First mappings, then literals $content = str_replace(array_keys($this->allpairs), $this->allpairs, $content); return $content; }
public function after_restore() { global $DB; if ($certificate = $DB->get_record('simplecertificate', array('id' => $this->get_activityid()))) { if ($certificate->certdate <= -1000) { // If less or equal -1000, is mark as not sucefully retored in stepslib $certificate->certdate = $certificate->certdate / -1000; if ($mapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $certificate->certdate)) { //If certdate == certgrade the function get_backup_ids_record for certgrade returns null, could be a bug if ($certificate->certdate == $certificate->certgrade / -1000) { $certificate->certgrade = $mapping->newitemid; } $certificate->certdate = $mapping->newitemid; } else { $this->get_logger()->process("Failed to restore dependency in simplecertificate 'certdate'. " . "Backup and restore will not work correctly unless you include the dependent module.", backup::LOG_ERROR); } } if ($certificate->certgrade <= -1000) { // If greater than 0, then it is a grade item value $certificate->certgrade = $certificate->certgrade / -1000; if ($mapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $certificate->certgrade)) { $certificate->certgrade = $mapping->newitemid; } else { $this->get_logger()->process("Failed to restore dependency in simplecertificate 'certgrade'. " . "Backup and restore will not work correctly unless you include the dependent module.", backup::LOG_ERROR); } } if (!$DB->update_record('simplecertificate', $certificate)) { throw new restore_task_exception('cannotrestore'); } // Process issued files if ($issues = $DB->get_records('simplecertificate_issues', array('certificateid' => $certificate->id))) { $fs = get_file_storage(); foreach ($issues as $issued) { try { $context = context_module::instance($this->get_moduleid()); if ($this->get_old_moduleversion() < 2014051000 && ($user = $DB->get_record("user", array('id' => $issued->userid)))) { $filename = str_replace(' ', '_', clean_filename($issued->certificatename . ' ' . fullname($user) . ' ' . $issued->pathnamehash . '.pdf')); } else { $filename = str_replace(' ', '_', clean_filename($issued->certificatename . ' ' . $issued->pathnamehash . '.pdf')); } $fileinfo = array('contextid' => $context->id, 'component' => 'mod_simplecertificate', 'filearea' => 'issues', 'itemid' => $issued->pathnamehash, 'filepath' => '/', 'filename' => $filename); if ($fs->file_exists($fileinfo['contextid'], $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $fileinfo['filename'])) { $file = $fs->get_file($fileinfo['contextid'], $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $fileinfo['filename']); $context = context_user::instance($issued->userid); $newfileinfo = $fileinfo; $newfileinfo['itemid'] = $issued->userid; $newfileinfo['filename'] = str_replace(' ', '_', clean_filename($issued->certificatename . ' ' . $issued->id . '.pdf')); if ($fs->file_exists($newfileinfo['contextid'], $newfileinfo['component'], $newfileinfo['filearea'], $newfileinfo['itemid'], $newfileinfo['filepath'], $newfileinfo['filename'])) { $newfile = $fs->get_file($newfileinfo['contextid'], $newfileinfo['component'], $newfileinfo['filearea'], $newfileinfo['itemid'], $newfileinfo['filepath'], $newfileinfo['filename']); } else { $newfile = $fs->create_file_from_storedfile($newfileinfo, $file); } $issued->pathnamehash = $newfile->get_pathnamehash(); $fs->delete_area_files($fileinfo['contextid'], $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid']); } else { throw new Exception('File not found'); } } catch (Exception $e) { $this->log(" Can't restore file {$filename}. " . $e->getMessage(), backup::LOG_WARNING); //$issued->pathnamehash = ''; $issued->haschange = 1; } if (!$DB->update_record('simplecertificate_issues', $issued)) { throw new restore_task_exception('cannotrestore'); } } } } }
/** * Looks for mapping values in backup_ids table, simple wrapper over get_backup_ids_record */ protected function get_mapping($itemname, $itemid) { // Check restoreid is set if (!$this->restoreid) { throw new restore_decode_rule_exception('decode_rule_restoreid_not_set'); } if (!($found = restore_dbops::get_backup_ids_record($this->restoreid, $itemname, $itemid))) { return false; } return $found->newitemid; }
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; }
/** * Re-map the dependency and activitylink information * If a depency or activitylink has no mapping in the backup data then it could either be a duplication of a * lesson, or a backup/restore of a single lesson. We have no way to determine which and whether this is the * same site and/or course. Therefore we try and retrieve a mapping, but fallback to the original value if one * was not found. We then test to see whether the value found is valid for the course being restored into. */ public function after_restore() { global $DB; $lesson = $DB->get_record('lesson', array('id' => $this->get_activityid()), 'id, course, dependency, activitylink'); $updaterequired = false; if (!empty($lesson->dependency)) { $updaterequired = true; if ($newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'lesson', $lesson->dependency)) { $lesson->dependency = $newitem->newitemid; } if (!$DB->record_exists('lesson', array('id' => $lesson->dependency, 'course' => $lesson->course))) { $lesson->dependency = 0; } } if (!empty($lesson->activitylink)) { $updaterequired = true; if ($newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $lesson->activitylink)) { $lesson->activitylink = $newitem->newitemid; } if (!$DB->record_exists('course_modules', array('id' => $lesson->activitylink, 'course' => $lesson->course))) { $lesson->activitylink = 0; } } if ($updaterequired) { $DB->update_record('lesson', $lesson); } }
/** * This function is responsible for handling the restoration process of the element. * * We will want to update the course module the date element is pointing to as it will * have changed in the course restore. * * @param restore_customcert_activity_task $restore */ public function after_restore($restore) { global $DB; $dateinfo = json_decode($this->element->data); if ($newitem = restore_dbops::get_backup_ids_record($restore->get_restoreid(), 'course_module', $dateinfo->dateitem)) { $dateinfo->dateitem = $newitem->newitemid; $DB->set_field('customcert_elements', 'data', self::save_unique_data($dateinfo), array('id' => $this->element->id)); } }
public function after_restore() { global $DB; // Get the new module $sql = "SELECT c.*\n FROM {certificate} c\n INNER JOIN {course_modules} cm\n ON c.id = cm.instance\n WHERE cm.id = :cmid"; if ($certificate = $DB->get_record_sql($sql, array('cmid' => $this->get_moduleid()))) { // A flag to check if we need to update the database or not $update = false; if ($certificate->printdate > 2) { // If greater than 2, then it is a grade item value if ($newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $certificate->printdate)) { $update = true; $certificate->printdate = $newitem->newitemid; } } if ($certificate->printgrade > 2) { if ($newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $certificate->printgrade)) { $update = true; $certificate->printgrade = $newitem->newitemid; } } if ($update) { // Update the certificate $DB->update_record('certificate', $certificate); } } }
/** * Called at the end of the entire restore process, once per subpage. * We use it to fix up the subpage section IDs. */ public function after_restore() { global $DB; $restoreid = $this->get_restoreid(); $subpageid = $this->get_activityid(); $needfixes = $DB->get_records_sql("\nSELECT\n ss.id, ss.sectionid AS oldsectionid, s.name AS name\nFROM\n {subpage} s\n JOIN {subpage_sections} ss ON ss.subpageid = s.id\nWHERE\n s.id = ?", array($subpageid)); $transaction = $DB->start_delegated_transaction(); foreach ($needfixes as $needfix) { $oldsectionid = $needfix->oldsectionid - 10000000; $mappingrecord = restore_dbops::get_backup_ids_record($restoreid, 'course_section', $oldsectionid); $newsectionid = $mappingrecord ? $mappingrecord->newitemid : false; if ($newsectionid) { $DB->set_field('subpage_sections', 'sectionid', $newsectionid, array('id' => $needfix->id)); } else { $this->get_logger()->process("Failed to restore section dependency " . "{$needfix->oldsectionid} in subpage '{$needfix->name}'. " . "Backup and restore will not work correctly unless you include " . "the relevant course sections.", backup::LOG_ERROR); } } $transaction->allow_commit(); }
/** * Return the complete mapping from the given itemname, itemid */ public function get_mapping($itemname, $oldid) { return restore_dbops::get_backup_ids_record($this->get_restoreid(), $itemname, $oldid); }
/** * Preform the restore_create_question_files step. */ protected function define_execution() { global $DB; // Track progress, as this task can take a long time. $progress = $this->task->get_progress(); $progress->start_progress($this->get_name(), \core\progress\base::INDETERMINATE); // Parentitemids of question_createds in backup_ids_temp are the category it is in. // MUST use a recordset, as there is no unique key in the first (or any) column. $catqtypes = $DB->get_recordset_sql("SELECT DISTINCT bi.parentitemid AS categoryid, q.qtype as qtype\n FROM {backup_ids_temp} bi\n JOIN {question} q ON q.id = bi.newitemid\n WHERE bi.backupid = ?\n AND bi.itemname = 'question_created'\n ORDER BY categoryid ASC", array($this->get_restoreid())); $currentcatid = -1; foreach ($catqtypes as $categoryid => $row) { $qtype = $row->qtype; // Check if we are in a new category. if ($currentcatid !== $categoryid) { // Report progress for each category. $progress->progress(); if (!($qcatmapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_category', $categoryid))) { // Something went really wrong, cannot find the question_category for the question_created records. debugging('Error fetching target context for question', DEBUG_DEVELOPER); continue; } // Calculate source and target contexts. $oldctxid = $qcatmapping->info->contextid; $newctxid = $qcatmapping->parentitemid; $this->send_common_files($oldctxid, $newctxid, $progress); $currentcatid = $categoryid; } $this->send_qtype_files($qtype, $oldctxid, $newctxid, $progress); } $catqtypes->close(); $progress->end_progress(); }
/** * Verify the xxx_ids_cached (in-memory backup_ids cache) stuff works as expected. * * Note that those private implementations are tested here by using the public * backup_ids API and later performing low-level tests. */ public function test_backup_ids_cached() { global $DB; $dbman = $DB->get_manager(); // We are going to use database_manager services. $this->resetAfterTest(true); // Playing with temp tables, better reset once finished. // Some variables and objects for testing. $restoreid = 'testrestoreid'; $mapping = new stdClass(); $mapping->itemname = 'user'; $mapping->itemid = 1; $mapping->newitemid = 2; $mapping->parentitemid = 3; $mapping->info = 'info'; // Create the backup_ids temp tables used by restore. restore_controller_dbops::create_restore_temp_tables($restoreid); // Send one mapping using the public api with defaults. restore_dbops::set_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid); // Get that mapping and verify everything is returned as expected. $result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid); $this->assertSame($mapping->itemname, $result->itemname); $this->assertSame($mapping->itemid, $result->itemid); $this->assertSame(0, $result->newitemid); $this->assertSame(null, $result->parentitemid); $this->assertSame(null, $result->info); // Drop the backup_xxx_temp temptables manually, so memory cache won't be invalidated. $dbman->drop_table(new xmldb_table('backup_ids_temp')); $dbman->drop_table(new xmldb_table('backup_files_temp')); // Verify the mapping continues returning the same info, // now from cache (the table does not exist). $result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid); $this->assertSame($mapping->itemname, $result->itemname); $this->assertSame($mapping->itemid, $result->itemid); $this->assertSame(0, $result->newitemid); $this->assertSame(null, $result->parentitemid); $this->assertSame(null, $result->info); // Recreate the temp table, just to drop it using the restore API in // order to check that, then, the cache becomes invalid for the same request. restore_controller_dbops::create_restore_temp_tables($restoreid); restore_controller_dbops::drop_restore_temp_tables($restoreid); // No cached info anymore, so the mapping request will arrive to // DB leading to error (temp table does not exist). try { $result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid); $this->fail('Expecting an exception, none occurred'); } catch (Exception $e) { $this->assertTrue($e instanceof dml_exception); $this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage()); } // Create the backup_ids temp tables once more. restore_controller_dbops::create_restore_temp_tables($restoreid); // Send one mapping using the public api with complete values. restore_dbops::set_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid, $mapping->newitemid, $mapping->parentitemid, $mapping->info); // Get that mapping and verify everything is returned as expected. $result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid); $this->assertSame($mapping->itemname, $result->itemname); $this->assertSame($mapping->itemid, $result->itemid); $this->assertSame($mapping->newitemid, $result->newitemid); $this->assertSame($mapping->parentitemid, $result->parentitemid); $this->assertSame($mapping->info, $result->info); // Finally, drop the temp tables properly and get the DB error again (memory caches empty). restore_controller_dbops::drop_restore_temp_tables($restoreid); try { $result = restore_dbops::get_backup_ids_record($restoreid, $mapping->itemname, $mapping->itemid); $this->fail('Expecting an exception, none occurred'); } catch (Exception $e) { $this->assertTrue($e instanceof dml_exception); $this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage()); } }