Script to run import on CLI?

Script to run import on CLI?

by Rex Lorenzo -
Number of replies: 6

Just wondering, does anyone have a script that they can share that performs a course import on the command-line (CLI)?

We have a course with a huge question bank that is failing to backup/restore properly and I want to run the import via CLI to avoid timeout issues. The import on the GUI is taking 2+ hours until something times out.

There is a CLI script to do the backup: https://github.com/moodle/moodle/blob/master/admin/cli/backup.php

And a moosh script to do the restore: https://github.com/tmuras/moosh/blob/master/Moosh/Command/Moodle33/Course/CourseRestore.php

But does anyone have any code on how to do the import via CLI? 

I tried looking at how to make this page CLI: https://github.com/moodle/moodle/blob/master/backup/import.php

But questions abound like:

  1. How do I set the backup controller to get to the final stage so it can execute?
  2. It seems I need to setup the import_ui(), but how do you step through it to get to the end via CLI?
  3. I see that backup::INTERACTIVE_YES is being set even on CLI scripts, what is it never not set to backup::INTERACTIVE_NO?

Just hoping someone did the heavy lifting from before and can share.

Average of ratings: -
In reply to Rex Lorenzo

Re: Script to run import on CLI?

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

I didn't understand your question at first because Moosh is a command line utility. The bit I misunderstood I think, is that you want to do question import not course import.

I wrote this which may contain some clues to solve your problem

https://github.com/marcusgreen/moodle-qtype_gapfill/blob/master/import_examples.php

However I wrote it back in 2015 so I have little recollection of the details.

In reply to Rex Lorenzo

Re: Script to run import on CLI?

by Andreas Grabs -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Translators

Hi Rex,

here is a basic example for importing a backup into an existing course:

<?php
require_once('config.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');

$backupfile = $CFG->dataroot.'/backup.mbz'; // The backup file you want to import from.
$courseid = 2; // The course you want to import in.

$admins = get_admins();
$admin = reset($admins);

// Unpack the backup.
$tempdir = random_string(20);
check_dir_exists($CFG->dataroot . '/temp/backup');

// We extract a stored_file or just a real file.
$fp = get_file_packer('application/vnd.moodle.backup');
$fp->extract_to_pathname($backupfile, $CFG->dataroot . '/temp/backup/' . $tempdir);

if (file_exists($CFG->dataroot.'/temp/backup/'.$tempdir.'/course/course.xml')) {
$controller = new \restore_controller($tempdir,
$courseid,
\backup::INTERACTIVE_NO,
\backup::MODE_IMPORT,
$admin->id,
\backup::TARGET_CURRENT_ADDING);

if (!$controller->execute_precheck()) {
if ($controller->get_status() !== \backup::STATUS_AWAITING) {
return false;
}
}

$controller->execute_plan();
rebuild_course_cache($courseid);

}

Best regards
Andreas

Average of ratings: Useful (1)
In reply to Andreas Grabs

Re: Script to run import on CLI?

by Rex Lorenzo -

I already have a script that can do the restore. It is the Moosh command here: https://github.com/tmuras/moosh/blob/master/Moosh/Command/Moodle33/Course/CourseRestore.php

Doesn't an import bypass the step of creating the mbz? The problem is that the creating the mbz backup file gives us this error:

php admin/cli/backup.php --courseid=58056 --destination=/tmp

== Performing backup... ==

!!! Coding error detected, it must be fixed by a programmer: File too large for .tar file: questions.xml (9326395069 bytes) !!!

That's why I want to write a script to do the import instead of doing a backup/restore.

In reply to Rex Lorenzo

Re: Script to run import on CLI?

by Andreas Grabs -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Translators

Ok, I understand.

The following example does a backup into a directory from a source course and import it into a destination course without creating a backup file.

<?php
require_once('config.php');
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . '/backup/controller/backup_controller.class.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');

$sourcecourse = 2;
$destcourse = 3;

$admin = get_admin();

///////////////////////////////////////////////////////////////////////////////
/// Backup into a directory
///////////////////////////////////////////////////////////////////////////////
$bc = new \backup_controller(\backup::TYPE_1COURSE, $sourcecourse,
\backup::FORMAT_MOODLE, \backup::INTERACTIVE_NO, \backup::MODE_IMPORT, $admin->id);

$bc->set_status(\backup::STATUS_AWAITING);

$outcome = $bc->execute_plan();
$results = $bc->get_results();

$backupdir = basename($bc->get_plan()->get_basepath());
$bc->destroy();
unset($bc);

///////////////////////////////////////////////////////////////////////////////
/// Restore from a directory
///////////////////////////////////////////////////////////////////////////////
if (file_exists($CFG->dataroot.'/temp/backup/'.$backupdir.'/course/course.xml')) {
$controller = new \restore_controller($backupdir,
$destcourse,
\backup::INTERACTIVE_NO,
// Possible option "backup::MODE_SAMESITE,".
\backup::MODE_IMPORT,
$admin->id,
// \backup::TARGET_NEW_COURSE);
\backup::TARGET_CURRENT_ADDING);
// \backup::TARGET_EXISTING_ADDING);
// \backup::TARGET_CURRENT_DELETING);
// \backup::TARGET_EXISTING_DELETING);

if (!$controller->execute_precheck()) {
if ($controller->get_status() !== \backup::STATUS_AWAITING) {
return false;
}
}

$controller->execute_plan();
rebuild_course_cache($destcourse);

}

I am hoping that helps.

Average of ratings: Useful (3)