Status quo
This commit is contained in:
parent
d44854e07b
commit
9fae3549f1
3 changed files with 360 additions and 13 deletions
136
import.php
Normal file
136
import.php
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
require_once("../../config.php");
|
||||||
|
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||||
|
require_once($CFG->dirroot . "/backup/util/includes/restore_includes.php");
|
||||||
|
|
||||||
|
$courseid = $_GET["courseid"];
|
||||||
|
$categoryid = $_GET["categoryid"];
|
||||||
|
$timestamp = $_GET["timestamp"];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$course = get_course($courseid);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$course = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$course) {
|
||||||
|
if (!get_course(((int) $courseid) - 1)) {
|
||||||
|
die("Cannot recreate course with this ID!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($course && !$categoryid) {
|
||||||
|
$categoryid = $course->category;
|
||||||
|
}
|
||||||
|
|
||||||
|
$category = $DB->get_record('course_categories', array('id' => $categoryid), '*', MUST_EXIST);
|
||||||
|
|
||||||
|
$replicationconfig = get_config('local_replication');
|
||||||
|
$directory = $replicationconfig->directory;
|
||||||
|
|
||||||
|
$infile = $directory . DIRECTORY_SEPARATOR . "course_" . $courseid . "_" . $categoryid . "_" . $timestamp . ".mbz";
|
||||||
|
|
||||||
|
if (empty($CFG->tempdir)) {
|
||||||
|
$CFG->tempdir = $CFG->dataroot . DIRECTORY_SEPARATOR . 'temp';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($infile)) {
|
||||||
|
die("Backup file '" . $infile . "' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_readable($infile)) {
|
||||||
|
die("Backup file '" . $infile . "' is not readable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$backupdir = "restore_" . uniqid();
|
||||||
|
|
||||||
|
if (isset($CFG->backuptempdir)){
|
||||||
|
$path = $CFG->backuptempdir . DIRECTORY_SEPARATOR . $backupdir;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$path = $CFG->tempdir . DIRECTORY_SEPARATOR . "backup" . DIRECTORY_SEPARATOR . $backupdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = get_file_packer('application/vnd.moodle.backup');
|
||||||
|
$fp->extract_to_pathname($infile, $path);
|
||||||
|
|
||||||
|
$xmlfile = $path . DIRECTORY_SEPARATOR . "course" . DIRECTORY_SEPARATOR . "course.xml";
|
||||||
|
|
||||||
|
$xml = simplexml_load_file($xmlfile);
|
||||||
|
$fullname = $xml->xpath('/course/fullname');
|
||||||
|
if (!$fullname) {
|
||||||
|
$fullname = $xml->xpath('/MOODLE_BACKUP/COURSE/HEADER/FULLNAME');
|
||||||
|
}
|
||||||
|
$shortname = $xml->xpath('/course/shortname');
|
||||||
|
if (!$shortname) {
|
||||||
|
$shortname = $xml->xpath('/MOODLE_BACKUP/COURSE/HEADER/SHORTNAME');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fullname = (string)($fullname[0]);
|
||||||
|
$shortname = (string)($shortname[0]);
|
||||||
|
|
||||||
|
if (!$fullname) {
|
||||||
|
$fullname = $shortname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$course && $DB->get_record('course', array('category' => $category->id, 'shortname' => $shortname))) {
|
||||||
|
$matches = NULL;
|
||||||
|
preg_match('/(.*)_(\d+)$/', $shortname, $matches);
|
||||||
|
if ($matches) {
|
||||||
|
$base = $matches[1];
|
||||||
|
$number = $matches[2];
|
||||||
|
} else {
|
||||||
|
$base = $shortname;
|
||||||
|
$number = 1;
|
||||||
|
}
|
||||||
|
$shortname = $base . '_' . $number;
|
||||||
|
while ($DB->get_record('course', array('category' => $category->id, 'shortname' => $shortname))) {
|
||||||
|
$number++;
|
||||||
|
$shortname = $base . '_' . $number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($course) {
|
||||||
|
echo "Overwriting current content of existing course -> Course ID: $courseid\n";
|
||||||
|
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_GENERAL, $USER->id, 0);
|
||||||
|
} else {
|
||||||
|
echo "Creating new course to restore backup\n";
|
||||||
|
$courseid = restore_dbops::create_new_course($fullname, $shortname, $category->id);
|
||||||
|
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_GENERAL, $USER->id, backup::TARGET_NEW_COURSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) {
|
||||||
|
$rc->convert();
|
||||||
|
}
|
||||||
|
|
||||||
|
$plan = $rc->get_plan();
|
||||||
|
|
||||||
|
if (!$rc->execute_precheck()){
|
||||||
|
$check = $rc->get_precheck_results();
|
||||||
|
echo("Restore pre-check failed!");
|
||||||
|
var_dump($check);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$deletingoptions = array();
|
||||||
|
$deletingoptions['keep_roles_and_enrolments'] = 1;
|
||||||
|
$deletingoptions['keep_groups_and_groupings'] = 1;
|
||||||
|
restore_dbops::delete_course_content($courseid, $deletingoptions);
|
||||||
|
|
||||||
|
$rc->execute_plan();
|
||||||
|
$rc->destroy();
|
||||||
|
|
||||||
|
#unlink($infile);
|
||||||
|
|
||||||
|
$course = get_course($courseid);
|
||||||
|
|
||||||
|
$course->category = $categoryid;
|
||||||
|
$course->fullname = $fullname;
|
||||||
|
$course->shortname = $shortname;
|
||||||
|
|
||||||
|
$DB->update_record('course', $course);
|
||||||
|
|
||||||
|
echo "New course ID for '$shortname': $courseid in category {$category->id}\n";
|
||||||
|
echo "OK"
|
194
import_cli.php
Normal file
194
import_cli.php
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
<?php
|
||||||
|
define('CLI_SCRIPT', true);
|
||||||
|
require_once("../../config.php");
|
||||||
|
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||||
|
require_once($CFG->dirroot . "/backup/util/includes/restore_includes.php");
|
||||||
|
require_once($CFG->libdir . '/clilib.php');
|
||||||
|
|
||||||
|
$usage = "Import a course from ContentMonster
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
# php import_cli.php --courseid=<value> --categoryid=<value> --timestamp=<value> [--source=<value>]
|
||||||
|
# php import_cli.php [--help|-h]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h --help Print this help.
|
||||||
|
--paramname=<value> Describe the parameter and the meaning of its values.
|
||||||
|
";
|
||||||
|
|
||||||
|
list($options, $unrecognised) = cli_get_params([
|
||||||
|
'help' => false,
|
||||||
|
'courseid' => null,
|
||||||
|
'categoryid' => null,
|
||||||
|
'timestamp' => null,
|
||||||
|
'source' => null,
|
||||||
|
], [
|
||||||
|
'h' => 'help'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($unrecognised) {
|
||||||
|
$unrecognised = implode(PHP_EOL . ' ', $unrecognised);
|
||||||
|
cli_error(get_string('cliunknowoption', 'core_admin', $unrecognised));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($options['help']) {
|
||||||
|
cli_writeln($usage);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($options['courseid'])) {
|
||||||
|
cli_error('Missing mandatory argument courseid.', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($options['categoryid'])) {
|
||||||
|
cli_error('Missing mandatory argument categoryid.', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($options['timestamp'])) {
|
||||||
|
cli_error('Missing mandatory argument timestamp.', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateRandomString($length = 10) {
|
||||||
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$charactersLength = strlen($characters);
|
||||||
|
$randomString = '';
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||||
|
}
|
||||||
|
return $randomString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$courseid = $options['courseid'];
|
||||||
|
$categoryid = $options["categoryid"];
|
||||||
|
$timestamp = $options["timestamp"];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$course = get_course($courseid);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
$course = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$category = $DB->get_record('course_categories', array('id' => $categoryid), '*', MUST_EXIST);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
cli_error('Category " . $categoryid . " does not exist.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$course) {
|
||||||
|
while (!get_course(((int) $courseid) - 1)) {
|
||||||
|
$name = generateRandomString();
|
||||||
|
$newcourse = restore_dbops::create_new_course("Placeholder " . $name, $name, $category->id);
|
||||||
|
if ((int) $newcourse > (int) $courseid) {
|
||||||
|
cli_error('Did you delete courses by any chance? Cannot create course ' . $courseid . '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$replicationconfig = get_config('local_replication');
|
||||||
|
$directory = $replicationconfig->directory;
|
||||||
|
|
||||||
|
$infile = $directory . DIRECTORY_SEPARATOR . "course_" . $courseid . "_" . $categoryid . "_" . $timestamp . ".mbz";
|
||||||
|
|
||||||
|
if (empty($CFG->tempdir)) {
|
||||||
|
$CFG->tempdir = $CFG->dataroot . DIRECTORY_SEPARATOR . 'temp';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($infile)) {
|
||||||
|
cli_error("Backup file '" . $infile . "' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_readable($infile)) {
|
||||||
|
cli_error("Backup file '" . $infile . "' is not readable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$backupdir = "restore_" . uniqid();
|
||||||
|
|
||||||
|
if (isset($CFG->backuptempdir)){
|
||||||
|
$path = $CFG->backuptempdir . DIRECTORY_SEPARATOR . $backupdir;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$path = $CFG->tempdir . DIRECTORY_SEPARATOR . "backup" . DIRECTORY_SEPARATOR . $backupdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = get_file_packer('application/vnd.moodle.backup');
|
||||||
|
$fp->extract_to_pathname($infile, $path);
|
||||||
|
|
||||||
|
$xmlfile = $path . DIRECTORY_SEPARATOR . "course" . DIRECTORY_SEPARATOR . "course.xml";
|
||||||
|
|
||||||
|
$xml = simplexml_load_file($xmlfile);
|
||||||
|
$fullname = $xml->xpath('/course/fullname');
|
||||||
|
if (!$fullname) {
|
||||||
|
$fullname = $xml->xpath('/MOODLE_BACKUP/COURSE/HEADER/FULLNAME');
|
||||||
|
}
|
||||||
|
$shortname = $xml->xpath('/course/shortname');
|
||||||
|
if (!$shortname) {
|
||||||
|
$shortname = $xml->xpath('/MOODLE_BACKUP/COURSE/HEADER/SHORTNAME');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fullname = (string)($fullname[0]);
|
||||||
|
$shortname = (string)($shortname[0]);
|
||||||
|
|
||||||
|
if (!$fullname) {
|
||||||
|
$fullname = $shortname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$course && $DB->get_record('course', array('category' => $category->id, 'shortname' => $shortname))) {
|
||||||
|
$matches = NULL;
|
||||||
|
preg_match('/(.*)_(\d+)$/', $shortname, $matches);
|
||||||
|
if ($matches) {
|
||||||
|
$base = $matches[1];
|
||||||
|
$number = $matches[2];
|
||||||
|
} else {
|
||||||
|
$base = $shortname;
|
||||||
|
$number = 1;
|
||||||
|
}
|
||||||
|
$shortname = $base . '_' . $number;
|
||||||
|
while ($DB->get_record('course', array('category' => $category->id, 'shortname' => $shortname))) {
|
||||||
|
$number++;
|
||||||
|
$shortname = $base . '_' . $number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($course) {
|
||||||
|
cli_writeln("Overwriting current content of existing course -> Course ID: $courseid");
|
||||||
|
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_GENERAL, 2, 0);
|
||||||
|
} else {
|
||||||
|
cli_writeln("Creating new course to restore backup");
|
||||||
|
$courseid = restore_dbops::create_new_course($fullname, $shortname, $category->id);
|
||||||
|
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_GENERAL, 2, backup::TARGET_NEW_COURSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) {
|
||||||
|
$rc->convert();
|
||||||
|
}
|
||||||
|
|
||||||
|
$plan = $rc->get_plan();
|
||||||
|
|
||||||
|
if (!$rc->execute_precheck()){
|
||||||
|
$check = $rc->get_precheck_results();
|
||||||
|
cli_error("Restore pre-check failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$deletingoptions = array();
|
||||||
|
$deletingoptions['keep_roles_and_enrolments'] = 1;
|
||||||
|
$deletingoptions['keep_groups_and_groupings'] = 1;
|
||||||
|
restore_dbops::delete_course_content($courseid, $deletingoptions);
|
||||||
|
|
||||||
|
$rc->execute_plan();
|
||||||
|
$rc->destroy();
|
||||||
|
|
||||||
|
#unlink($infile);
|
||||||
|
|
||||||
|
$course = get_course($courseid);
|
||||||
|
|
||||||
|
$course->category = $categoryid;
|
||||||
|
$course->fullname = $fullname;
|
||||||
|
$course->shortname = $shortname;
|
||||||
|
|
||||||
|
$DB->update_record('course', $course);
|
||||||
|
|
||||||
|
cli_writeln("New course ID for '$shortname': $courseid in category {$category->id}");
|
||||||
|
cli_writeln("OK");
|
41
trigger.php
41
trigger.php
|
@ -1,13 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
|
||||||
if (! function_exists('str_ends_with')) {
|
|
||||||
function str_ends_with(string $haystack, string $needle): bool
|
|
||||||
{
|
|
||||||
$needle_len = strlen($needle);
|
|
||||||
return ($needle_len === 0 || 0 === substr_compare($haystack, $needle, - $needle_len));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $_GET["id"];
|
$id = $_GET["id"];
|
||||||
$course = get_course($id);
|
$course = get_course($id);
|
||||||
|
@ -15,14 +8,38 @@ $course = get_course($id);
|
||||||
$replicationconfig = get_config('local_replication');
|
$replicationconfig = get_config('local_replication');
|
||||||
$directory = $replicationconfig->directory;
|
$directory = $replicationconfig->directory;
|
||||||
|
|
||||||
if (!str_ends_with($directory, "/")) $directory = $directory . "/";
|
|
||||||
|
|
||||||
$context = context_course::instance($id);
|
$context = context_course::instance($id);
|
||||||
|
|
||||||
if (!has_capability('local/replication:replicate', $context)) {
|
if (!has_capability('local/replication:replicate', $context)) {
|
||||||
die("User not allowed to trigger replication!");
|
die("User not allowed to trigger replication!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!touch($directory . $id . "-" . $course->category . ".mew")) {
|
$bc = new backup_controller(\backup::TYPE_1COURSE, $id, backup::FORMAT_MOODLE,
|
||||||
die("Could not touch $directory$id-{$course->category}.mew");
|
backup::INTERACTIVE_YES, backup::MODE_GENERAL, $USER->id);
|
||||||
|
|
||||||
|
$tasks = $bc->get_plan()->get_tasks();
|
||||||
|
foreach ($tasks as &$task) {
|
||||||
|
if ($task instanceof \backup_root_task) {
|
||||||
|
$setting = $task->get_setting('users');
|
||||||
|
$setting->set_value('0');
|
||||||
|
$setting = $task->get_setting('anonymize');
|
||||||
|
$setting->set_value('1');
|
||||||
|
$setting = $task->get_setting('role_assignments');
|
||||||
|
$setting->set_value('0');
|
||||||
|
$setting = $task->get_setting('filters');
|
||||||
|
$setting->set_value('0');
|
||||||
|
$setting = $task->get_setting('comments');
|
||||||
|
$setting->set_value('0');
|
||||||
|
$setting = $task->get_setting('logs');
|
||||||
|
$setting->set_value('0');
|
||||||
|
$setting = $task->get_setting('grade_histories');
|
||||||
|
$setting->set_value('0');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$filename = $directory . '/course_' . $id . "_" . $course->category . "_" . date('U') . '.mbz';
|
||||||
|
|
||||||
|
$bc->set_status(backup::STATUS_AWAITING);
|
||||||
|
$bc->execute_plan();
|
||||||
|
|
||||||
|
echo('Course is now getting replicated. <a href="javascript:history.back();">Back to Course Administration</a>');
|
||||||
|
|
Loading…
Reference in a new issue