mirror of
https://github.com/moodle/moodle.git
synced 2025-08-06 01:16:44 +02:00
MDL-47178 question: Retain question authors when restoring backups.
This commit is contained in:
parent
c71355941b
commit
1f3aacf8fc
3 changed files with 203 additions and 6 deletions
|
@ -4711,10 +4711,28 @@ class restore_create_categories_and_questions extends restore_structure_step {
|
||||||
}
|
}
|
||||||
|
|
||||||
$userid = $this->get_mappingid('user', $data->createdby);
|
$userid = $this->get_mappingid('user', $data->createdby);
|
||||||
$data->createdby = $userid ? $userid : $this->task->get_userid();
|
if ($userid) {
|
||||||
|
// The question creator is included in the backup, so we can use their mapping id.
|
||||||
|
$data->createdby = $userid;
|
||||||
|
} else {
|
||||||
|
// Leave the question creator unchanged when we are restoring the same site.
|
||||||
|
// Otherwise use current user id.
|
||||||
|
if (!$this->task->is_samesite()) {
|
||||||
|
$data->createdby = $this->task->get_userid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$userid = $this->get_mappingid('user', $data->modifiedby);
|
$userid = $this->get_mappingid('user', $data->modifiedby);
|
||||||
$data->modifiedby = $userid ? $userid : $this->task->get_userid();
|
if ($userid) {
|
||||||
|
// The question modifier is included in the backup, so we can use their mapping id.
|
||||||
|
$data->modifiedby = $userid;
|
||||||
|
} else {
|
||||||
|
// Leave the question modifier unchanged when we are restoring the same site.
|
||||||
|
// Otherwise use current user id.
|
||||||
|
if (!$this->task->is_samesite()) {
|
||||||
|
$data->modifiedby = $this->task->get_userid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// With newitemid = 0, let's create the question
|
// With newitemid = 0, let's create the question
|
||||||
if (!$questionmapping->newitemid) {
|
if (!$questionmapping->newitemid) {
|
||||||
|
|
|
@ -208,4 +208,178 @@ class core_question_backup_testcase extends advanced_testcase {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the question author is retained when they are enrolled in to the course.
|
||||||
|
*/
|
||||||
|
public function test_backup_question_author_retained_when_enrolled() {
|
||||||
|
global $DB, $USER, $CFG;
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$this->setAdminUser();
|
||||||
|
|
||||||
|
// Create a course, a category and a user.
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
$category = $this->getDataGenerator()->create_category();
|
||||||
|
$user = $this->getDataGenerator()->create_user();
|
||||||
|
|
||||||
|
// Create a question.
|
||||||
|
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||||
|
$questioncategory = $questiongenerator->create_question_category();
|
||||||
|
$overrides = ['category' => $questioncategory->id, 'createdby' => $user->id, 'modifiedby' => $user->id];
|
||||||
|
$question = $questiongenerator->create_question('truefalse', null, $overrides);
|
||||||
|
|
||||||
|
// Create a quiz and a questions.
|
||||||
|
$quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
|
||||||
|
quiz_add_quiz_question($question->id, $quiz);
|
||||||
|
|
||||||
|
// Enrol user with a teacher role.
|
||||||
|
$teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
|
||||||
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id, 'manual');
|
||||||
|
|
||||||
|
// Backup the course.
|
||||||
|
$bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
|
||||||
|
backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id);
|
||||||
|
$backupid = $bc->get_backupid();
|
||||||
|
$bc->execute_plan();
|
||||||
|
$results = $bc->get_results();
|
||||||
|
$file = $results['backup_destination'];
|
||||||
|
$fp = get_file_packer('application/vnd.moodle.backup');
|
||||||
|
$filepath = $CFG->dataroot . '/temp/backup/' . $backupid;
|
||||||
|
$file->extract_to_pathname($fp, $filepath);
|
||||||
|
$bc->destroy();
|
||||||
|
|
||||||
|
// Delete the original course and related question.
|
||||||
|
delete_course($course, false);
|
||||||
|
question_delete_question($question->id);
|
||||||
|
|
||||||
|
// Restore the course.
|
||||||
|
$restoredcourseid = restore_dbops::create_new_course($course->fullname, $course->shortname . '_1', $category->id);
|
||||||
|
$rc = new restore_controller($backupid, $restoredcourseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_GENERAL, $USER->id, backup::TARGET_NEW_COURSE);
|
||||||
|
$rc->execute_precheck();
|
||||||
|
$rc->execute_plan();
|
||||||
|
$rc->destroy();
|
||||||
|
|
||||||
|
// Test the question author.
|
||||||
|
$questions = $DB->get_records('question');
|
||||||
|
$this->assertCount(1, $questions);
|
||||||
|
$question3 = array_shift($questions);
|
||||||
|
$this->assertEquals($user->id, $question3->createdby);
|
||||||
|
$this->assertEquals($user->id, $question3->modifiedby);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the question author is retained when they are not enrolled in to the course,
|
||||||
|
* but we are restoring the backup at the same site.
|
||||||
|
*/
|
||||||
|
public function test_backup_question_author_retained_when_not_enrolled() {
|
||||||
|
global $DB, $USER, $CFG;
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$this->setAdminUser();
|
||||||
|
|
||||||
|
// Create a course, a category and a user.
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
$category = $this->getDataGenerator()->create_category();
|
||||||
|
$user = $this->getDataGenerator()->create_user();
|
||||||
|
|
||||||
|
// Create a question.
|
||||||
|
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||||
|
$questioncategory = $questiongenerator->create_question_category();
|
||||||
|
$overrides = ['category' => $questioncategory->id, 'createdby' => $user->id, 'modifiedby' => $user->id];
|
||||||
|
$question = $questiongenerator->create_question('truefalse', null, $overrides);
|
||||||
|
|
||||||
|
// Create a quiz and a questions.
|
||||||
|
$quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
|
||||||
|
quiz_add_quiz_question($question->id, $quiz);
|
||||||
|
|
||||||
|
// Backup the course.
|
||||||
|
$bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
|
||||||
|
backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id);
|
||||||
|
$backupid = $bc->get_backupid();
|
||||||
|
$bc->execute_plan();
|
||||||
|
$results = $bc->get_results();
|
||||||
|
$file = $results['backup_destination'];
|
||||||
|
$fp = get_file_packer('application/vnd.moodle.backup');
|
||||||
|
$filepath = $CFG->dataroot . '/temp/backup/' . $backupid;
|
||||||
|
$file->extract_to_pathname($fp, $filepath);
|
||||||
|
$bc->destroy();
|
||||||
|
|
||||||
|
// Delete the original course and related question.
|
||||||
|
delete_course($course, false);
|
||||||
|
question_delete_question($question->id);
|
||||||
|
|
||||||
|
// Restore the course.
|
||||||
|
$restoredcourseid = restore_dbops::create_new_course($course->fullname, $course->shortname . '_1', $category->id);
|
||||||
|
$rc = new restore_controller($backupid, $restoredcourseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_GENERAL, $USER->id, backup::TARGET_NEW_COURSE);
|
||||||
|
$rc->execute_precheck();
|
||||||
|
$rc->execute_plan();
|
||||||
|
$rc->destroy();
|
||||||
|
|
||||||
|
// Test the question author.
|
||||||
|
$questions = $DB->get_records('question');
|
||||||
|
$this->assertCount(1, $questions);
|
||||||
|
$question = array_shift($questions);
|
||||||
|
$this->assertEquals($user->id, $question->createdby);
|
||||||
|
$this->assertEquals($user->id, $question->modifiedby);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the current user is set as a question author when we are restoring the backup
|
||||||
|
* at the another site and the question author is not enrolled in to the course.
|
||||||
|
*/
|
||||||
|
public function test_backup_question_author_reset() {
|
||||||
|
global $DB, $USER, $CFG;
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$this->setAdminUser();
|
||||||
|
|
||||||
|
// Create a course, a category and a user.
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
$category = $this->getDataGenerator()->create_category();
|
||||||
|
$user = $this->getDataGenerator()->create_user();
|
||||||
|
|
||||||
|
// Create a question.
|
||||||
|
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||||
|
$questioncategory = $questiongenerator->create_question_category();
|
||||||
|
$overrides = ['category' => $questioncategory->id, 'createdby' => $user->id, 'modifiedby' => $user->id];
|
||||||
|
$question = $questiongenerator->create_question('truefalse', null, $overrides);
|
||||||
|
|
||||||
|
// Create a quiz and a questions.
|
||||||
|
$quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id));
|
||||||
|
quiz_add_quiz_question($question->id, $quiz);
|
||||||
|
|
||||||
|
// Backup the course.
|
||||||
|
$bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
|
||||||
|
backup::INTERACTIVE_NO, backup::MODE_SAMESITE, $USER->id);
|
||||||
|
$backupid = $bc->get_backupid();
|
||||||
|
$bc->execute_plan();
|
||||||
|
$results = $bc->get_results();
|
||||||
|
$file = $results['backup_destination'];
|
||||||
|
$fp = get_file_packer('application/vnd.moodle.backup');
|
||||||
|
$filepath = $CFG->dataroot . '/temp/backup/' . $backupid;
|
||||||
|
$file->extract_to_pathname($fp, $filepath);
|
||||||
|
$bc->destroy();
|
||||||
|
|
||||||
|
// Delete the original course and related question.
|
||||||
|
delete_course($course, false);
|
||||||
|
question_delete_question($question->id);
|
||||||
|
|
||||||
|
// Emulate restoring to a different site.
|
||||||
|
set_config('siteidentifier', random_string(32) . 'not the same site');
|
||||||
|
|
||||||
|
// Restore the course.
|
||||||
|
$restoredcourseid = restore_dbops::create_new_course($course->fullname, $course->shortname . '_1', $category->id);
|
||||||
|
$rc = new restore_controller($backupid, $restoredcourseid, backup::INTERACTIVE_NO,
|
||||||
|
backup::MODE_SAMESITE, $USER->id, backup::TARGET_NEW_COURSE);
|
||||||
|
$rc->execute_precheck();
|
||||||
|
$rc->execute_plan();
|
||||||
|
$rc->destroy();
|
||||||
|
|
||||||
|
// Test the question author.
|
||||||
|
$questions = $DB->get_records('question');
|
||||||
|
$this->assertCount(1, $questions);
|
||||||
|
$question = array_shift($questions);
|
||||||
|
$this->assertEquals($USER->id, $question->createdby);
|
||||||
|
$this->assertEquals($USER->id, $question->modifiedby);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,10 +129,15 @@ class core_question_generator extends component_generator_base {
|
||||||
|
|
||||||
$question = question_bank::get_qtype($qtype)->save_question($question, $fromform);
|
$question = question_bank::get_qtype($qtype)->save_question($question, $fromform);
|
||||||
|
|
||||||
if ($overrides && array_key_exists('createdby', $overrides)) {
|
if ($overrides && (array_key_exists('createdby', $overrides) || array_key_exists('modifiedby', $overrides))) {
|
||||||
// Manually update the createdby because questiontypebase forces current user and some tests require a
|
// Manually update the createdby and modifiedby because questiontypebase forces
|
||||||
// specific user.
|
// current user and some tests require a specific user.
|
||||||
|
if (array_key_exists('createdby', $overrides)) {
|
||||||
$question->createdby = $overrides['createdby'];
|
$question->createdby = $overrides['createdby'];
|
||||||
|
}
|
||||||
|
if (array_key_exists('modifiedby', $overrides)) {
|
||||||
|
$question->modifiedby = $overrides['modifiedby'];
|
||||||
|
}
|
||||||
$DB->update_record('question', $question);
|
$DB->update_record('question', $question);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue