/** * Extracts the file. * * @param string|stored_file $source Archive file to extract * @return bool */ protected function extract_file_to_dir($source) { global $CFG, $USER; $this->filepath = restore_controller::get_tempdir_name($this->contextid, $USER->id); $fb = get_file_packer('application/vnd.moodle.backup'); $result = $fb->extract_to_pathname($source, $CFG->tempdir . '/backup/' . $this->filepath . '/', null, $this); // If any progress happened, end it. if ($this->startedprogress) { $this->get_progress_reporter()->end_progress(); } return $result; }
protected function extract_file_to_dir() { global $CFG, $USER; $this->filepath = restore_controller::get_tempdir_name($this->contextid, $USER->id); $fb = get_file_packer(); return $fb->extract_to_pathname("{$CFG->tempdir}/backup/" . $this->filename, "{$CFG->tempdir}/backup/{$this->filepath}/"); }
$restore_url = new moodle_url('/backup/restore.php', array('contextid' => $contextid, 'filename' => $filename)); redirect($restore_url); } else { redirect($url, get_string('filenotfound', 'error')); } die; } $PAGE->set_url($url); $PAGE->set_context($context); $PAGE->set_title(get_string('course') . ': ' . $course->fullname); $PAGE->set_heading($heading); $PAGE->set_pagelayout('admin'); $form = new course_restore_form(null, array('contextid' => $contextid)); $data = $form->get_data(); if ($data && has_capability('moodle/restore:uploadfile', $context)) { $filename = restore_controller::get_tempdir_name($course->id, $USER->id); $pathname = $tmpdir . '/' . $filename; $form->save_file('backupfile', $pathname); $restore_url = new moodle_url('/backup/restore.php', array('contextid' => $contextid, 'filename' => $filename)); redirect($restore_url); die; } echo $OUTPUT->header(); // require uploadfile cap to use file picker if (has_capability('moodle/restore:uploadfile', $context)) { echo $OUTPUT->heading(get_string('importfile', 'backup')); echo $OUTPUT->container_start(); $form->display(); echo $OUTPUT->container_end(); } if ($context->contextlevel == CONTEXT_MODULE) {
/** * Restore an item from the recycle bin. * * @param \stdClass $item The item database record * @throws \moodle_exception */ public function restore_item($item) { global $CFG, $OUTPUT, $PAGE; require_once $CFG->dirroot . '/backup/util/includes/restore_includes.php'; require_once $CFG->dirroot . '/course/lib.php'; $user = get_admin(); // Grab the course category context. $context = \context_coursecat::instance($this->_categoryid); // Get the backup file. $fs = get_file_storage(); $files = $fs->get_area_files($context->id, 'tool_recyclebin', TOOL_RECYCLEBIN_COURSECAT_BIN_FILEAREA, $item->id, 'itemid, filepath, filename', false); if (empty($files)) { throw new \moodle_exception('Invalid recycle bin item!'); } if (count($files) > 1) { throw new \moodle_exception('Too many files found!'); } // Get the backup file. $file = reset($files); // Get a temp directory name and create it. $tempdir = \restore_controller::get_tempdir_name($context->id, $user->id); $fulltempdir = make_temp_directory('/backup/' . $tempdir); // Extract the backup to tmpdir. $fb = get_file_packer('application/vnd.moodle.backup'); $fb->extract_to_pathname($file, $fulltempdir); // Build a course. $course = new \stdClass(); $course->category = $this->_categoryid; $course->shortname = $item->shortname; $course->fullname = $item->fullname; $course->summary = ''; // Create a new course. $course = create_course($course); if (!$course) { throw new \moodle_exception("Could not create course to restore into."); } // Define the import. $controller = new \restore_controller($tempdir, $course->id, \backup::INTERACTIVE_NO, \backup::MODE_GENERAL, $user->id, \backup::TARGET_NEW_COURSE); // Prechecks. if (!$controller->execute_precheck()) { $results = $controller->get_precheck_results(); // Check if errors have been found. if (!empty($results['errors'])) { // Delete the temporary file we created. fulldelete($fulltempdir); // Delete the course we created. delete_course($course, false); echo $OUTPUT->header(); $backuprenderer = $PAGE->get_renderer('core', 'backup'); echo $backuprenderer->precheck_notices($results); echo $OUTPUT->continue_button(new \moodle_url('/course/index.php', array('categoryid' => $this->_categoryid))); echo $OUTPUT->footer(); exit; } } // Run the import. $controller->execute_plan(); // Have finished with the controller, let's destroy it, freeing mem and resources. $controller->destroy(); // Fire event. $event = \tool_recyclebin\event\category_bin_item_restored::create(array('objectid' => $item->id, 'context' => $context)); $event->add_record_snapshot('tool_recyclebin_category', $item); $event->trigger(); // Cleanup. fulldelete($fulltempdir); $this->delete_item($item); }
/** * Get the restore content tempdir. * * The tempdir is the sub directory in which the backup has been extracted. * * This caches the result for better performance, but $CFG->keeptempdirectoriesonbackup * needs to be enabled, otherwise the cache is ignored. * * @param string $backupfile path to a backup file. * @param string $shortname shortname of a course. * @param array $errors will be populated with errors found. * @return string|false false when the backup couldn't retrieved. */ public static function get_restore_content_dir($backupfile = null, $shortname = null, &$errors = array()) { global $CFG, $DB, $USER; $cachekey = null; if (!empty($backupfile)) { $backupfile = realpath($backupfile); if (empty($backupfile) || !is_readable($backupfile)) { $errors['cannotreadbackupfile'] = new lang_string('cannotreadbackupfile', 'tool_uploadcourse'); return false; } $cachekey = 'backup_path:' . $backupfile; } else { if (!empty($shortname) || is_numeric($shortname)) { $cachekey = 'backup_sn:' . $shortname; } } if (empty($cachekey)) { return false; } // If $CFG->keeptempdirectoriesonbackup is not set to true, any restore happening would // automatically delete the backup directory... causing the cache to return an unexisting directory. $usecache = !empty($CFG->keeptempdirectoriesonbackup); if ($usecache) { $cache = cache::make('tool_uploadcourse', 'helper'); } // If we don't use the cache, or if we do and not set, or the directory doesn't exist any more. if (!$usecache || (($backupid = $cache->get($cachekey)) === false || !is_dir("{$CFG->tempdir}/backup/{$backupid}"))) { // Use null instead of false because it would consider that the cache key has not been set. $backupid = null; if (!empty($backupfile)) { // Extracting the backup file. $packer = get_file_packer('application/vnd.moodle.backup'); $backupid = restore_controller::get_tempdir_name(SITEID, $USER->id); $path = "{$CFG->tempdir}/backup/{$backupid}/"; $result = $packer->extract_to_pathname($backupfile, $path); if (!$result) { $errors['invalidbackupfile'] = new lang_string('invalidbackupfile', 'tool_uploadcourse'); } } else { if (!empty($shortname) || is_numeric($shortname)) { // Creating restore from an existing course. $courseid = $DB->get_field('course', 'id', array('shortname' => $shortname), IGNORE_MISSING); if (!empty($courseid)) { $bc = new backup_controller(backup::TYPE_1COURSE, $courseid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id); $bc->execute_plan(); $backupid = $bc->get_backupid(); $bc->destroy(); } else { $errors['coursetorestorefromdoesnotexist'] = new lang_string('coursetorestorefromdoesnotexist', 'tool_uploadcourse'); } } } if ($usecache) { $cache->set($cachekey, $backupid); } } if ($backupid === null) { $backupid = false; } return $backupid; }
/** * Restore an item from the recycle bin. * * @param \stdClass $item The item database record * @throws \moodle_exception */ public function restore_item($item) { global $CFG, $OUTPUT, $PAGE; require_once $CFG->dirroot . '/backup/util/includes/restore_includes.php'; $user = get_admin(); // Grab the course context. $context = \context_course::instance($this->_courseid); // Get the files.. $fs = get_file_storage(); $files = $fs->get_area_files($context->id, 'tool_recyclebin', TOOL_RECYCLEBIN_COURSE_BIN_FILEAREA, $item->id, 'itemid, filepath, filename', false); if (empty($files)) { throw new \moodle_exception('Invalid recycle bin item!'); } if (count($files) > 1) { throw new \moodle_exception('Too many files found!'); } // Get the backup file. $file = reset($files); // Get a temp directory name and create it. $tempdir = \restore_controller::get_tempdir_name($context->id, $user->id); $fulltempdir = make_temp_directory('/backup/' . $tempdir); // Extract the backup to tempdir. $fb = get_file_packer('application/vnd.moodle.backup'); $fb->extract_to_pathname($file, $fulltempdir); // Define the import. $controller = new \restore_controller($tempdir, $this->_courseid, \backup::INTERACTIVE_NO, \backup::MODE_GENERAL, $user->id, \backup::TARGET_EXISTING_ADDING); // Prechecks. if (!$controller->execute_precheck()) { $results = $controller->get_precheck_results(); // If errors are found then delete the file we created. if (!empty($results['errors'])) { fulldelete($fulltempdir); echo $OUTPUT->header(); $backuprenderer = $PAGE->get_renderer('core', 'backup'); echo $backuprenderer->precheck_notices($results); echo $OUTPUT->continue_button(new \moodle_url('/course/view.php', array('id' => $this->_courseid))); echo $OUTPUT->footer(); exit; } } // Run the import. $controller->execute_plan(); // Fire event. $event = \tool_recyclebin\event\course_bin_item_restored::create(array('objectid' => $item->id, 'context' => $context)); $event->add_record_snapshot('tool_recyclebin_course', $item); $event->trigger(); // Cleanup. fulldelete($fulltempdir); $this->delete_item($item); }