Merge branch 'MDL-68314-master' of git://github.com/aanabit/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 13 May 2020 11:15:17 +0000 (13:15 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 13 May 2020 11:15:17 +0000 (13:15 +0200)
15 files changed:
admin/settings/courses.php
backup/moodle2/backup_course_task.class.php
backup/moodle2/backup_root_task.class.php
backup/moodle2/backup_settingslib.php
backup/moodle2/backup_stepslib.php
backup/moodle2/restore_course_task.class.php
backup/moodle2/restore_root_task.class.php
backup/moodle2/restore_settingslib.php
backup/moodle2/restore_stepslib.php
backup/moodle2/tests/moodle2_test.php
backup/util/dbops/backup_controller_dbops.class.php
backup/util/dbops/restore_controller_dbops.class.php
backup/util/ui/tests/behat/import_contentbank_content.feature [new file with mode: 0644]
lang/en/backup.php
version.php

index 841b72b..8936f7c 100644 (file)
@@ -235,6 +235,11 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
             new lang_string('generalgroups', 'backup'), new lang_string('configgeneralgroups', 'backup'),
             array('value' => 1, 'locked' => 0)));
     $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_competencies', new lang_string('generalcompetencies','backup'), new lang_string('configgeneralcompetencies','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_contentbankcontent',
+        new lang_string('generalcontentbankcontent', 'backup'),
+        new lang_string('configgeneralcontentbankcontent', 'backup'),
+        ['value' => 1, 'locked' => 0])
+    );
 
     $ADMIN->add('backups', $temp);
 
@@ -256,6 +261,12 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
             new lang_string('generalgroups', 'backup'), new lang_string('configgeneralgroups', 'backup'),
             array('value' => 1, 'locked' => 0)));
     $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_import_competencies', new lang_string('generalcompetencies','backup'), new lang_string('configgeneralcompetencies','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock(
+        'backup/backup_import_contentbankcontent',
+        new lang_string('generalcontentbankcontent', 'backup'),
+        new lang_string('configgeneralcontentbankcontent', 'backup'),
+        ['value' => 1, 'locked' => 0])
+    );
 
     $ADMIN->add('backups', $temp);
 
@@ -375,6 +386,12 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
     $temp->add(new admin_setting_configcheckbox('backup/backup_auto_groups', new lang_string('generalgroups', 'backup'),
             new lang_string('configgeneralgroups', 'backup'), 1));
     $temp->add(new admin_setting_configcheckbox('backup/backup_auto_competencies', new lang_string('generalcompetencies','backup'), new lang_string('configgeneralcompetencies','backup'), 1));
+    $temp->add(new admin_setting_configcheckbox(
+        'backup/backup_auto_contentbankcontent',
+        new lang_string('generalcontentbankcontent', 'backup'),
+        new lang_string('configgeneralcontentbankcontent', 'backup'),
+        1)
+    );
 
     //$temp->add(new admin_setting_configcheckbox('backup/backup_auto_messages', new lang_string('messages', 'message'), new lang_string('backupmessageshelp','message'), 0));
     //$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blogs', new lang_string('blogs', 'blog'), new lang_string('backupblogshelp','blog'), 0));
@@ -435,6 +452,9 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
     $temp->add(new admin_setting_configcheckbox_with_lock('restore/restore_general_competencies',
         new lang_string('generalcompetencies', 'backup'),
         new lang_string('configrestorecompetencies', 'backup'), array('value' => 1, 'locked' => 0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('restore/restore_general_contentbankcontent',
+        new lang_string('generalcontentbankcontent', 'backup'),
+        new lang_string('configrestorecontentbankcontent', 'backup'), array('value' => 1, 'locked' => 0)));
 
     // Restore defaults when merging into another course.
     $temp->add(new admin_setting_heading('mergerestoredefaults', new lang_string('mergerestoredefaults', 'backup'), ''));
index d9060e3..d2ac8c5 100644 (file)
@@ -139,6 +139,11 @@ class backup_course_task extends backup_task {
         // Migrate the already exported inforef entries to final ones
         $this->add_step(new move_inforef_annotations_to_final('migrate_inforef'));
 
+        // Generate the content bank file (conditionally).
+        if ($this->get_setting_value('contentbankcontent')) {
+            $this->add_step(new backup_contentbankcontent_structure_step('course_contentbank', 'contentbank.xml'));
+        }
+
         // At the end, mark it as built
         $this->built = true;
     }
index ee434c1..4771c39 100644 (file)
@@ -179,5 +179,10 @@ class backup_root_task extends backup_task {
         $customfields = new backup_customfield_setting('customfield', base_setting::IS_BOOLEAN, true);
         $customfields->set_ui(new backup_setting_ui_checkbox($customfields, get_string('rootsettingcustomfield', 'backup')));
         $this->add_setting($customfields);
+
+        // Define content bank content inclusion setting.
+        $contentbank = new backup_contentbankcontent_setting('contentbankcontent', base_setting::IS_BOOLEAN, true);
+        $contentbank->set_ui(new backup_setting_ui_checkbox($contentbank, get_string('rootsettingcontentbankcontent', 'backup')));
+        $this->add_setting($contentbank);
     }
 }
index 9125673..59ea252 100644 (file)
@@ -199,3 +199,9 @@ class backup_activity_included_setting extends activity_backup_setting {}
  * user information or no, depends of @backup_users_setting
  */
 class backup_activity_userinfo_setting extends activity_backup_setting {}
+
+/**
+ * Root setting to control if backup will include content bank content or no
+ */
+class backup_contentbankcontent_setting extends backup_generic_setting {
+}
index ac8c917..cf0115a 100644 (file)
@@ -2740,3 +2740,34 @@ class backup_completion_defaults_structure_step extends backup_structure_step {
 
     }
 }
+
+/**
+ * Structure step in charge of constructing the contentbank.xml file for all the contents found in a given context
+ */
+class backup_contentbankcontent_structure_step extends backup_structure_step {
+
+    /**
+     * Define structure for content bank step
+     */
+    protected function define_structure() {
+
+        // Define each element separated.
+        $contents = new backup_nested_element('contents');
+        $content = new backup_nested_element('content', ['id'], [
+            'name', 'contenttype', 'instanceid', 'configdata', 'usercreated', 'usermodified', 'timecreated', 'timemodified']);
+
+        // Build the tree.
+        $contents->add_child($content);
+
+        // Define sources.
+        $content->set_source_table('contentbank_content', ['contextid' => backup::VAR_CONTEXTID]);
+
+        // Define annotations.
+        $content->annotate_ids('user', 'usercreated');
+        $content->annotate_ids('user', 'usermodified');
+        $content->annotate_files('contentbank', 'public', 'id');
+
+        // Return the root element (contents).
+        return $contents;
+    }
+}
index 6bcf826..be4f3f9 100644 (file)
@@ -126,6 +126,11 @@ class restore_course_task extends restore_task {
         // Activity completion defaults.
         $this->add_step(new restore_completion_defaults_structure_step('course_completion_defaults', 'completiondefaults.xml'));
 
+        // Content bank content (conditionally).
+        if ($this->get_setting_value('contentbankcontent')) {
+            $this->add_step(new restore_contentbankcontent_structure_step('course_contentbank', 'contentbank.xml'));
+        }
+
         // At the end, mark it as built
         $this->built = true;
     }
index 3069a0b..632985f 100644 (file)
@@ -290,5 +290,17 @@ class restore_root_task extends restore_task {
         $customfields = new restore_customfield_setting('customfields', base_setting::IS_BOOLEAN, $defaultvalue);
         $customfields->set_ui(new backup_setting_ui_checkbox($customfields, get_string('rootsettingcustomfield', 'backup')));
         $this->add_setting($customfields);
+
+        // Define Content bank content.
+        $defaultvalue = false;
+        $changeable = false;
+        if (isset($rootsettings['contentbankcontent']) && $rootsettings['contentbankcontent']) { // Only enabled when available.
+            $defaultvalue = true;
+            $changeable = true;
+        }
+        $contents = new restore_contentbankcontent_setting('contentbankcontent', base_setting::IS_BOOLEAN, $defaultvalue);
+        $contents->set_ui(new backup_setting_ui_checkbox($contents, get_string('rootsettingcontentbankcontent', 'backup')));
+        $contents->get_ui()->set_changeable($changeable);
+        $this->add_setting($contents);
     }
 }
index daa3fec..61124de 100644 (file)
@@ -236,3 +236,9 @@ class restore_activity_included_setting extends restore_activity_generic_setting
  * user information or no, depends of @restore_users_setting
  */
 class restore_activity_userinfo_setting extends restore_activity_generic_setting {}
+
+/**
+ * root setting to control if restore will create content bank content or no
+ */
+class restore_contentbankcontent_setting extends restore_generic_setting {
+}
index 10199e0..223b849 100644 (file)
@@ -3984,6 +3984,60 @@ class restore_activity_grade_history_structure_step extends restore_structure_st
     }
 }
 
+/**
+ * This structure steps restores the content bank content
+ */
+class restore_contentbankcontent_structure_step extends restore_structure_step {
+
+    /**
+     * Define structure for content bank step
+     */
+    protected function define_structure() {
+
+        $paths = [];
+        $paths[] = new restore_path_element('contentbankcontent', '/contents/content');
+
+        return $paths;
+    }
+
+    /**
+     * Define data processed for content bank
+     *
+     * @param mixed  $data
+     */
+    public function process_contentbankcontent($data) {
+        global $DB;
+
+        $data = (object)$data;
+        $oldid = $data->id;
+
+        $params = [
+            'name'           => $data->name,
+            'contextid'      => $this->task->get_contextid(),
+            'contenttype'    => $data->contenttype,
+            'instanceid'     => $data->instanceid,
+            'timecreated'    => $data->timecreated,
+        ];
+        $exists = $DB->record_exists('contentbank_content', $params);
+        if (!$exists) {
+            $params['configdata'] = $data->configdata;
+            $params['usercreated'] = $this->get_mappingid('user', $data->usercreated);
+            $params['usermodified'] = $this->get_mappingid('user', $data->usermodified);
+            $params['timemodified'] = time();
+            $newitemid = $DB->insert_record('contentbank_content', $params);
+            $this->set_mapping('contentbank_content', $oldid, $newitemid, true);
+        }
+    }
+
+    /**
+     * Define data processed after execute for content bank
+     */
+    protected function after_execute() {
+        // Add related files.
+        $this->add_related_files('contentbank', 'public', 'contentbank_content');
+    }
+}
+
 /**
  * This structure steps restores one instance + positions of one block
  * Note: Positions corresponding to one existing context are restored
index 6649934..b4fed99 100644 (file)
@@ -1063,4 +1063,32 @@ class core_backup_moodle2_testcase extends advanced_testcase {
             }
         }
     }
+
+    /**
+     * Test the content bank content through a backup and restore.
+     */
+    public function test_contentbank_content_backup() {
+        global $DB, $USER, $CFG;
+        $this->resetAfterTest();
+
+        $this->setAdminUser();
+        $generator = $this->getDataGenerator();
+        $cbgenerator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
+
+        // Create course and add content bank content.
+        $course = $generator->create_course();
+        $context = context_course::instance($course->id);
+        $filepath = $CFG->dirroot . '/h5p/tests/fixtures/filltheblanks.h5p';
+        $contents = $cbgenerator->generate_contentbank_data('contenttype_h5p', 2, $USER->id, $context, true, $filepath);
+        $this->assertEquals(2, $DB->count_records('contentbank_content'));
+
+        // Do backup and restore.
+        $newcourseid = $this->backup_and_restore($course);
+
+        // Confirm that values were transferred correctly into content bank on new course.
+        $newcontext = context_course::instance($newcourseid);
+
+        $this->assertEquals(4, $DB->count_records('contentbank_content'));
+        $this->assertEquals(2, $DB->count_records('contentbank_content', ['contextid' => $newcontext->id]));
+    }
 }
index ce9c1ba..9e09f55 100644 (file)
@@ -564,7 +564,8 @@ abstract class backup_controller_dbops extends backup_dbops {
                         'backup_general_histories'          => 'grade_histories',
                         'backup_general_questionbank'       => 'questionbank',
                         'backup_general_groups'             => 'groups',
-                        'backup_general_competencies'       => 'competencies'
+                        'backup_general_competencies'       => 'competencies',
+                        'backup_general_contentbankcontent' => 'contentbankcontent',
                 );
                 self::apply_admin_config_defaults($controller, $settings, true);
                 break;
@@ -577,7 +578,8 @@ abstract class backup_controller_dbops extends backup_dbops {
                         'backup_import_calendarevents'     => 'calendarevents',
                         'backup_import_questionbank'       => 'questionbank',
                         'backup_import_groups'             => 'groups',
-                        'backup_import_competencies'       => 'competencies'
+                        'backup_import_competencies'       => 'competencies',
+                        'backup_import_contentbankcontent' => 'contentbankcontent',
                 );
                 self::apply_admin_config_defaults($controller, $settings, true);
                 if ((!$controller->get_interactive()) &&
@@ -608,7 +610,8 @@ abstract class backup_controller_dbops extends backup_dbops {
                         'backup_auto_histories'          => 'grade_histories',
                         'backup_auto_questionbank'       => 'questionbank',
                         'backup_auto_groups'             => 'groups',
-                        'backup_auto_competencies'       => 'competencies'
+                        'backup_auto_competencies'       => 'competencies',
+                        'backup_auto_contentbankcontent' => 'contentbankcontent'
                 );
                 self::apply_admin_config_defaults($controller, $settings, false);
                 break;
index 6649777..148655b 100644 (file)
@@ -157,7 +157,8 @@ abstract class restore_controller_dbops extends restore_dbops {
             'restore_general_histories'          => 'grade_histories',
             'restore_general_questionbank'       => 'questionbank',
             'restore_general_groups'             => 'groups',
-            'restore_general_competencies'       => 'competencies'
+            'restore_general_competencies'       => 'competencies',
+            'restore_general_contentbankcontent' => 'contentbankcontent'
         );
         self::apply_admin_config_defaults($controller, $settings, true);
 
diff --git a/backup/util/ui/tests/behat/import_contentbank_content.feature b/backup/util/ui/tests/behat/import_contentbank_content.feature
new file mode 100644 (file)
index 0000000..68f2fb3
--- /dev/null
@@ -0,0 +1,45 @@
+@core @core_backup @core_contentbank
+Feature: Import course content bank content
+  In order to import content from a course contentbank
+  As a teacher
+  I need to confirm that errors will not happen
+
+  Background:
+    Given the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1        | 0        |
+      | Course 2 | C2        | 0        |
+    And the following "users" exist:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@example.com |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | teacher1 | C2 | editingteacher |
+    And the following "contentbank content" exist:
+      | course| contenttype     | user     | contentname       |
+      | C1    | contenttype_h5p | teacher1 | ipsums.h5p        |
+    And I log in as "teacher1"
+
+  Scenario: Import content bank content to another course
+    Given I am on "Course 2" course homepage
+    And I click on "Content bank" "link"
+    And I should not see "ipsums.h5p"
+    When I import "Course 1" course into "Course 2" course using this options:
+    And I click on "Content bank" "link"
+    Then I should see "ipsums.h5p"
+    And I am on "Course 1" course homepage
+    And I click on "Content bank" "link"
+    And I should see "ipsums.h5p"
+
+  Scenario: User could configure not to import content bank
+    Given I am on "Course 2" course homepage
+    And I click on "Content bank" "link"
+    And I should not see "ipsums.h5p"
+    When I import "Course 1" course into "Course 2" course using this options:
+      | Initial | Include content bank content | 0 |
+    And I click on "Content bank" "link"
+    Then I should not see "ipsums.h5p"
+    And I am on "Course 1" course homepage
+    And I click on "Content bank" "link"
+    And I should see "ipsums.h5p"
index 0c08c50..c59daba 100644 (file)
@@ -127,6 +127,7 @@ $string['configgeneralblocks'] = 'Sets the default for including blocks in a bac
 $string['configgeneralcalendarevents'] = 'Sets the default for including calendar events in a backup.';
 $string['configgeneralcomments'] = 'Sets the default for including comments in a backup.';
 $string['configgeneralcompetencies'] = 'Sets the default for including competencies in a backup.';
+$string['configgeneralcontentbankcontent'] = 'Sets the default for including content bank content in a backup.';
 $string['configgeneralfiles'] = 'Sets the default for including files in a backup. Please note: Disabling this setting will result in a backup which only includes references to files. This is not a problem if the backup is restored on the same site and the files have not been deleted according to the setting \'Clean up trash pool files\' (filescleanupperiod).';
 $string['configgeneralfilters'] = 'Sets the default for including filters in a backup.';
 $string['configgeneralhistories'] = 'Sets the default for including user history within a backup.';
@@ -143,6 +144,7 @@ $string['configrestoreblocks'] = 'Sets the default for restoring blocks.';
 $string['configrestorecalendarevents'] = 'Sets the default for restoring calendar events.';
 $string['configrestorecomments'] = 'Sets the default for restoring comments.';
 $string['configrestorecompetencies'] = 'Sets the default for restoring competencies.';
+$string['configrestorecontentbankcontent'] = 'Sets the default for restoring content bank content.';
 $string['configrestoreenrolments'] = 'Sets the default for restoring enrolment methods.';
 $string['configrestorefilters'] = 'Sets the default for restoring filters.';
 $string['configrestorehistories'] = 'Sets the default for restoring user history if it was included in the backup.';
@@ -202,6 +204,7 @@ $string['generalblocks'] = 'Include blocks';
 $string['generalcalendarevents'] = 'Include calendar events';
 $string['generalcomments'] = 'Include comments';
 $string['generalcompetencies'] = 'Include competencies';
+$string['generalcontentbankcontent'] = 'Include content bank content';
 $string['generalenrolments'] = 'Include enrolment methods';
 $string['generalfiles'] = 'Include files';
 $string['generalfilters'] = 'Include filters';
@@ -333,6 +336,7 @@ $string['rootsettingfilters'] = 'Include filters';
 $string['rootsettingfiles'] = 'Include files';
 $string['rootsettingcomments'] = 'Include comments';
 $string['rootsettingcalendarevents'] = 'Include calendar events';
+$string['rootsettingcontentbankcontent'] = 'Include content bank content';
 $string['rootsettinguserscompletion'] = 'Include user completion details';
 $string['rootsettingquestionbank'] = 'Include question bank';
 $string['rootsettinglogs'] = 'Include course logs';
index c02fa52..dd63fb5 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2020051200.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2020051200.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.
 $release  = '3.9dev+ (Build: 20200512)'; // Human-friendly version name