Skip to content

Commit

Permalink
quiz-data - First pass at import whole course
Browse files Browse the repository at this point in the history
  • Loading branch information
EJMFarrow committed Nov 8, 2024
1 parent b4434b8 commit 4143720
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 92 deletions.
46 changes: 5 additions & 41 deletions classes/cli_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ class cli_helper {
* QUIZ_FILE - File name ending for quiz structure file.
*/
public const QUIZ_FILE = '_quiz.json';
/**
* QUIZPATH_FILE - File name for quiz location file.
*/
public const QUIZPATH_FILE = 'quizlocation.json';
/**
* TEMP_MANIFEST_FILE - File name ending for temporary manifest file.
* Appended to name of moodle instance.
Expand Down Expand Up @@ -445,19 +441,13 @@ public static function get_quiz_directory(string $basedirectory, string $quiznam
* @param object $manifestcontents \stdClass Current contents of manifest file
* @param string $tempfilepath
* @param string $manifestpath
* @param string $moodleurl
* @param int|null $subcategoryid
* @param string|null $subdirectory
* @param bool $showupdated
* @param object $activity
* @return object
*/
public static function create_manifest_file(object $manifestcontents, string $tempfilepath,
string $manifestpath, string $moodleurl,
?int $subcategoryid=null,
?string $subdirectory=null,
bool $showupdated=true,
object $activity=null):object {
public static function create_manifest_file(object $manifestcontents,
string $tempfilepath,
string $manifestpath,
bool $showupdated=true):object {
// Read in temp file a question at a time, process and add to manifest.
// No actual processing at the moment so could simplify to write straight
// to manifest in the first place if no processing materialises.
Expand Down Expand Up @@ -498,34 +488,8 @@ public static function create_manifest_file(object $manifestcontents, string $te
$existingentries["{$questioninfo->questionbankentryid}"]->moodlecommit = $questioninfo->moodlecommit;
}
}
if ($manifestcontents->context === null) {
$manifestcontents->context = new \stdClass();
$manifestcontents->context->contextlevel = $questioninfo->contextlevel;
$manifestcontents->context->coursename = $questioninfo->coursename;
$manifestcontents->context->modulename = $questioninfo->modulename;
$manifestcontents->context->coursecategory = $questioninfo->coursecategory;
$manifestcontents->context->instanceid = $questioninfo->instanceid;
$manifestcontents->context->defaultsubcategoryid = $subcategoryid;
$manifestcontents->context->defaultsubdirectory = $subdirectory;
$manifestcontents->context->defaultignorecat = $questioninfo->ignorecat;
$manifestcontents->context->moodleurl = $moodleurl;
}
}
}
// If there are no questions, we'll need to get context.
if ($manifestcontents->context === null) {
$context = $activity->cli_helper->check_context($activity, false, true);
$manifestcontents->context = new \stdClass();
$manifestcontents->context->contextlevel = $questioninfo->contextlevel;
$manifestcontents->context->coursename = $questioninfo->coursename;
$manifestcontents->context->modulename = $questioninfo->modulename;
$manifestcontents->context->coursecategory = $questioninfo->coursecategory;
$manifestcontents->context->instanceid = $questioninfo->instanceid;
$manifestcontents->context->defaultsubcategoryid = $subcategoryid;
$manifestcontents->context->defaultsubdirectory = $subdirectory;
$manifestcontents->context->defaultignorecat = $questioninfo->ignorecat;
$manifestcontents->context->moodleurl = $moodleurl;
}
echo "\nAdded {$addedcount} question" . (($addedcount !== 1) ? 's' : '') . ".\n";
if ($showupdated) {
echo "Updated {$updatedcount} question" . (($updatedcount !== 1) ? 's' : '') . ".\n";
Expand Down Expand Up @@ -650,7 +614,7 @@ public function create_gitignore(string $manifestpath):void {
$ignore = fopen($manifestdirname . '/.gitignore', 'a');

$contents = "**/*" . self::MANIFEST_FILE . "\n**/*" .
self::TEMP_MANIFEST_FILE . "\n**/" . self::QUIZPATH_FILE . "\n";
self::TEMP_MANIFEST_FILE . "\n";
fwrite($ignore, $contents);
fclose($ignore);
}
Expand Down
19 changes: 14 additions & 5 deletions classes/create_repo.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) {
$this->tempfilepath = str_replace(cli_helper::MANIFEST_FILE,
'_export' . cli_helper::TEMP_MANIFEST_FILE,
$this->manifestpath);
$this->manifestcontents = new \stdClass();
$this->manifestcontents->context = new \stdClass();
$this->manifestcontents->context->contextlevel = cli_helper::get_context_level($instanceinfo->contextinfo->contextlevel);
$this->manifestcontents->context->coursename = $instanceinfo->contextinfo->coursename;
$this->manifestcontents->context->modulename = $instanceinfo->contextinfo->modulename;
$this->manifestcontents->context->coursecategory = $instanceinfo->contextinfo->categoryname;
$this->manifestcontents->context->instanceid = $instanceinfo->contextinfo->instanceid;
$this->manifestcontents->context->defaultsubcategoryid = $this->qcategoryid;
$this->manifestcontents->context->defaultsubdirectory = null;
$this->manifestcontents->context->defaultignorecat = $this->ignorecat;
$this->manifestcontents->context->moodleurl = $this->moodleurl;
$this->manifestcontents->questions = [];
}

/**
Expand All @@ -206,13 +218,10 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) {
* @return void
*/
public function process():void {
$this->manifestcontents = new \stdClass();
$this->manifestcontents->context = null;
$this->manifestcontents->questions = [];
$this->export_to_repo();
$this->manifestcontents->context->defaultsubdirectory = $this->subdirectory;
cli_helper::create_manifest_file($this->manifestcontents, $this->tempfilepath,
$this->manifestpath, $this->moodleurl,
$this->qcategoryid, $this->subdirectory, false, $this);
$this->manifestpath, false);
unlink($this->tempfilepath);
}

Expand Down
3 changes: 1 addition & 2 deletions classes/export_repo.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ public function process():void {
// Export any questions that are in Moodle but not in the manifest.
$this->export_to_repo();
cli_helper::create_manifest_file($this->manifestcontents, $this->tempfilepath,
$this->manifestpath, $this->moodleurl,
null, null, false, $this);
$this->manifestpath, false);
unlink($this->tempfilepath);
// Remove questions from manifest that are no longer in Moodle.
// Will be restored from repo on next import if file is still there.
Expand Down
6 changes: 0 additions & 6 deletions classes/export_trait.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,8 @@ public function export_to_repo_main_process(object $moodlequestionlist):void {
$fileoutput = [
'questionbankentryid' => $questioninfo->questionbankentryid,
'version' => $responsejson->version,
'contextlevel' => $this->listpostsettings['contextlevel'],
'filepath' => str_replace( '\\', '/', $bottomdirectory) . "/{$sanitisedqname}.xml",
'coursename' => $this->listpostsettings['coursename'],
'modulename' => $this->listpostsettings['modulename'],
'coursecategory' => $this->listpostsettings['coursecategory'],
'instanceid' => $this->listpostsettings['instanceid'],
'format' => 'xml',
'ignorecat' => $this->ignorecat,
];
fwrite($tempfile, json_encode($fileoutput) . "\n");
}
Expand Down
38 changes: 16 additions & 22 deletions classes/import_repo.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) {
if ($arguments['directory']) {
$this->directory = $arguments['rootdirectory'] . '/' . $arguments['directory'];
} else {
if ($manifestpath) {
if ($manifestpath && dirname($manifestpath) !== '.') {
$this->directory = $arguments['rootdirectory'] . '/' . dirname($manifestpath);
} else {
$this->directory = $arguments['rootdirectory'];
Expand Down Expand Up @@ -290,7 +290,16 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) {
$this->call_exit();
} else if (!$manifestcontents && !$manifestpath) {
$this->manifestcontents = new \stdClass();
$this->manifestcontents->context = null;
$this->manifestcontents->context = new \stdClass();
$this->manifestcontents->context->contextlevel = cli_helper::get_context_level($instanceinfo->contextinfo->contextlevel);
$this->manifestcontents->context->coursename = $instanceinfo->contextinfo->coursename;
$this->manifestcontents->context->modulename = $instanceinfo->contextinfo->modulename;
$this->manifestcontents->context->coursecategory = $instanceinfo->contextinfo->categoryname;
$this->manifestcontents->context->instanceid = $instanceinfo->contextinfo->instanceid;
$this->manifestcontents->context->defaultsubcategoryid = $instanceinfo->contextinfo->qcategoryid;
$this->manifestcontents->context->defaultsubdirectory = $this->subdirectory;
$this->manifestcontents->context->defaultignorecat = $this->ignorecat;
$this->manifestcontents->context->moodleurl = $this->moodleurl;
$this->manifestcontents->questions = [];
} else {
$this->manifestcontents = $manifestcontents;
Expand Down Expand Up @@ -336,7 +345,9 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) {
$this->listpostsettings['qcategoryname'] = $qcategoryname;
$this->listcurlrequest->set_option(CURLOPT_POSTFIELDS, $this->listpostsettings);

if (count($this->manifestcontents->questions) === 0) {
if (count($this->manifestcontents->questions) === 0 && !$arguments['quiet']) {
// A quiz in a whole course set up can have an empty manifest as
// the questions may be in the course.
echo "\nManifest file is empty. This should only be the case if you are importing ";
echo "questions for the first time into a Moodle context where they don't already exist.\n";
$this->handle_abort();
Expand All @@ -352,15 +363,10 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) {
public function process():void {
$this->import_categories();
$this->import_questions();
$instanceinfo = $this->clihelper->check_context($this, true, true);
$this->manifestcontents = cli_helper::create_manifest_file($this->manifestcontents,
$this->tempfilepath,
$this->manifestpath,
$this->moodleurl,
$instanceinfo->contextinfo->qcategoryid,
$this->subdirectory,
true,
$this);
true);
unlink($this->tempfilepath);
$this->delete_no_file_questions(false);
$this->delete_no_record_questions(false);
Expand Down Expand Up @@ -555,15 +561,8 @@ public function import_questions() {
$fileoutput = [
'questionbankentryid' => $responsejson->questionbankentryid,
'version' => $responsejson->version,
// Questions can be imported in multiple contexts.
'contextlevel' => $this->postsettings['contextlevel'],
'filepath' => str_replace( '\\', '/', $repoitem->getPathname()),
'coursename' => $this->postsettings['coursename'],
'modulename' => $this->postsettings['modulename'],
'coursecategory' => $this->postsettings['coursecategory'],
'instanceid' => $this->postsettings['instanceid'],
'format' => 'xml',
'ignorecat' => $this->ignorecat,
];
if ($existingentry && isset($existingentry->currentcommit)) {
$fileoutput['moodlecommit'] = $existingentry->currentcommit;
Expand Down Expand Up @@ -596,15 +595,10 @@ public function import_questions() {
public function recovery():void {
if (file_exists($this->tempfilepath)) {
echo 'Attempting recovery from failure on previous run. Updating manifest:';
$instanceinfo = $this->clihelper->check_context($this, true, true);
$this->manifestcontents = cli_helper::create_manifest_file($this->manifestcontents,
$this->tempfilepath,
$this->manifestpath,
$this->moodleurl,
$instanceinfo->contextinfo->qcategoryid,
$this->subdirectory,
true,
$this);
true);
unlink($this->tempfilepath);
echo 'Recovery successful. Continuing...';
}
Expand Down
22 changes: 14 additions & 8 deletions cli/createwholecourserepo.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,28 +165,34 @@
$moodleinstance = $arguments['moodleinstance'];
$coursemanifestname = cli_helper::get_manifest_path($moodleinstance, 'course', null,
$contextinfo->contextinfo->coursename, null, $basedirectory);
$contentsjson = file_get_contents($coursemanifestname);
$manifestcontents = json_decode($contentsjson);

$instanceid = $arguments['instanceid'];
$token = $arguments['token'][$moodleinstance];
$ignorecat = $arguments['ignorecat'];
$ignorecat = ($ignorecat) ? ' -x "' . $ignorecat . '"' : '';
$quizfilepath = $basedirectory . '/' . $clihelper::QUIZPATH_FILE;
$quiz_locations = [];
$quizlocations = [];
foreach ($contextinfo->quizzes as $quiz) {
$instanceid = "{$quiz->instanceid}";
$instanceid = $quiz->instanceid;
$quizdirectory = cli_helper::get_quiz_directory($basedirectory, $quiz->name);
$rootdirectory = $clihelper->create_directory($quizdirectory);
echo "\nExporting quiz: {$quiz->name} to {$rootdirectory}\n";
chdir($scriptdirectory);
$output = shell_exec('php createrepo.php -r "' . $rootdirectory . '" -i "' . $moodleinstance . '" -l "module" -n ' . (int) $instanceid . ' -t ' . $token . ' -z' . $ignorecat);
$output = shell_exec('php createrepo.php -r "' . $rootdirectory . '" -i "' . $moodleinstance . '" -l "module" -n ' . $instanceid . ' -t ' . $token . ' -z' . $ignorecat);
echo $output;
$quizmanifestname = cli_helper::get_manifest_path($moodleinstance, 'module', null,
$contextinfo->contextinfo->coursename, $quiz->name, $rootdirectory);
chdir($scriptdirectory);
$output = shell_exec('php exportquizstructurefrommoodle.php -z -r "" -i "' . $moodleinstance . '" -n ' . (int) $instanceid . ' -t ' . $token. ' -p "' . $coursemanifestname. '" -f "' . $quizmanifestname . '"');
$quiz_locations[$instanceid] = basename($rootdirectory);
$success = file_put_contents($quizfilepath, json_encode($quiz_locations));
$output = shell_exec('php exportquizstructurefrommoodle.php -z -r "" -i "' . $moodleinstance . '" -n ' . $instanceid . ' -t ' . $token. ' -p "' . $coursemanifestname. '" -f "' . $quizmanifestname . '"');
$quizlocation = new StdClass();
$quizlocation->moduleid = $instanceid;
$quizlocation->directory = basename($rootdirectory);
$quizlocations[] = $quizlocation;
$manifestcontents->quizzes = $quizlocations;
$success = file_put_contents($coursemanifestname, json_encode($manifestcontents));
if ($success === false) {
echo "\nUnable to update quizpath file: {$quizfilepath}\n Aborting.\n";
echo "\nUnable to update manifest file: {$coursemanifestname}\n Aborting.\n";
exit();
}
echo $output;
Expand Down
Loading

0 comments on commit 4143720

Please sign in to comment.