MDL-69448 backup: fix capability checks when unable to copy user data.
authorPaul Holden <paulh@moodle.com>
Tue, 11 Aug 2020 23:57:57 +0000 (00:57 +0100)
committerPaul Holden <paulh@moodle.com>
Fri, 4 Sep 2020 07:19:53 +0000 (08:19 +0100)
When a given user doesn't have the capability to "Include user data"
during course copying, freeze the form element rather than not adding
it at all.

This caused problems as the element was required before preceding with
the course copy.

backup/util/ui/classes/copy/copy.php
backup/util/ui/classes/output/copy_form.php
lang/en/backup.php
lib/classes/task/asynchronous_copy_task.php

index 3e2d269..496cf02 100644 (file)
@@ -111,8 +111,8 @@ class copy  {
      *  Take the validated form data and extract the required information for copy operations.
      *
      * @param \stdClass $formdata Data from the validated course copy form.
-     * @throws \moodle_exception
      * @return \stdClass $copydata Data required for course copy operations.
+     * @throws \moodle_exception If one of the required copy fields is missing
      */
     private final function get_copy_data(\stdClass $formdata): \stdClass {
         $copydata = new \stdClass();
@@ -121,7 +121,7 @@ class copy  {
             if (isset($formdata->{$field})) {
                 $copydata->{$field} = $formdata->{$field};
             } else {
-                throw new \moodle_exception('copy_class_field_not_found');
+                throw new \moodle_exception('copyfieldnotfound', 'backup', '', null, $field);
             }
         }
 
index 34794a8..6856101 100644 (file)
@@ -162,15 +162,17 @@ class copy_form extends \moodleform {
         }
 
         // Keep source course user data.
+        $mform->addElement('select', 'userdata', get_string('userdata', 'backup'),
+            [0 => get_string('no'), 1 => get_string('yes')]);
+        $mform->setDefault('userdata', 0);
+        $mform->addHelpButton('userdata', 'userdata', 'backup');
+
         $requiredcapabilities = array(
             'moodle/restore:createuser', 'moodle/backup:userinfo', 'moodle/restore:userinfo'
         );
-        if (has_all_capabilities($requiredcapabilities, $coursecontext)) {
-            $dataarray = array();
-            $dataarray[] = $mform->createElement('advcheckbox', 'userdata',
-                get_string('enable'), '', array('group' => 1), array(0, 1));
-            $mform->addGroup($dataarray, 'dataarray', get_string('userdata', 'backup'), ' ', false);
-            $mform->addHelpButton('dataarray', 'userdata', 'backup');
+        if (!has_all_capabilities($requiredcapabilities, $coursecontext)) {
+            $mform->hardFreeze('userdata');
+            $mform->setConstants('userdata', 0);
         }
 
         // Keep manual enrolments.
index 4bf99b4..f13cc48 100644 (file)
@@ -169,6 +169,7 @@ $string['copycoursetitle'] = 'Copy course: {$a}';
 $string['copydest'] = 'Destination';
 $string['copyingcourse'] = 'Course copying in progress';
 $string['copyingcourseshortname'] = 'copying';
+$string['copyfieldnotfound'] = 'A required field was not found';
 $string['copyformfail'] = 'AJAX submission of course copy form has failed.';
 $string['copyop'] = 'Current operation';
 $string['copyprogressheading'] = 'Course copies in progress';
index 6504d40..0f7bb41 100644 (file)
@@ -72,14 +72,16 @@ class asynchronous_copy_task extends adhoc_task {
         $keepuserdata = (bool)$copyinfo->userdata;
         $keptroles = $copyinfo->keptroles;
 
-        $backupplan->get_setting('users')->set_value('1');
         $bc->set_kept_roles($keptroles);
 
         // If we are not keeping user data don't include users or data in the backup.
         // In this case we'll add the user enrolments at the end.
         // Also if we have no roles to keep don't backup users.
         if (empty($keptroles) || !$keepuserdata) {
+            $backupplan->get_setting('users')->set_status(\backup_setting::NOT_LOCKED);
             $backupplan->get_setting('users')->set_value('0');
+        } else {
+            $backupplan->get_setting('users')->set_value('1');
         }
 
         // Do some preflight checks on the backup.