backup MDL-22140 Added conf settings to control the default general backup settings
authorSam Hemelryk <sam@moodle.com>
Thu, 17 Jun 2010 08:57:00 +0000 (08:57 +0000)
committerSam Hemelryk <sam@moodle.com>
Thu, 17 Jun 2010 08:57:00 +0000 (08:57 +0000)
14 files changed:
admin/settings/courses.php
backup/controller/backup_controller.class.php
backup/util/dbops/backup_controller_dbops.class.php
backup/util/settings/base_setting.class.php
backup/util/settings/setting_dependency.class.php
backup/util/ui/backup_moodleform.class.php
backup/util/ui/backup_ui_setting.class.php
files/index.php
lang/en/admin.php
lang/en/backup.php
lib/adminlib.php
pix/i/configlock.gif [new file with mode: 0644]
pix/i/hierarchylock.gif [new file with mode: 0644]
pix/i/permissionlock.gif [new file with mode: 0644]

index e3b3fad..bfa4dfa 100644 (file)
@@ -129,8 +129,26 @@ if ($hassiteconfig
                 $CFG->wwwroot . '/course/pending.php', array('moodle/site:approvecourse')));
     }
 
+    // Add a category for backups
+    $ADMIN->add('courses', new admin_category('backups', get_string('backups','admin')));
+
+    // Create a page for general backup defaults
+    $temp = new admin_settingpage('backupgeneralsettings', get_string('generalbackdefaults', 'backup'), 'moodle/backup:backupcourse');
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_users', get_string('generalusers','backup'), get_string('configgeneralusers','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_anonymize', get_string('generalanonymize','backup'), get_string('configgeneralanonymize','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_role_assignments', get_string('generalroleassignments','backup'), get_string('configgeneralroleassignments','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_user_files', get_string('generaluserfiles','backup'), get_string('configgeneraluserfiles','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_activities', get_string('generalactivities','backup'), get_string('configgeneralactivities','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_blocks', get_string('generalblocks','backup'), get_string('configgeneralblocks','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_filters', get_string('generalfilters','backup'), get_string('configgeneralfilters','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_comments', get_string('generalcomments','backup'), get_string('configgeneralcomments','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_userscompletion', get_string('generaluserscompletion','backup'), get_string('configgeneraluserscompletion','backup'), array('value'=>1, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_logs', get_string('generallogs','backup'), get_string('configgenerallogs','backup'), array('value'=>0, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_histories', get_string('generalhistories','backup'), get_string('configgeneralhistories','backup'), array('value'=>0, 'locked'=>0)));
+    $ADMIN->add('backups', $temp);
+
 /// "backups" settingpage
-    $temp = new admin_settingpage('backups', get_string('backups','admin'), 'moodle/backup:backupcourse');
+    $temp = new admin_settingpage('scheduled', get_string('scheduledsettings','backup'), 'moodle/backup:backupcourse');
     $temp->add(new admin_setting_configcheckbox('backup/backup_sche_modules', get_string('includemodules'), get_string('backupincludemoduleshelp'), 0));
     $temp->add(new admin_setting_configcheckbox('backup/backup_sche_withuserdata', get_string('includemoduleuserdata'), get_string('backupincludemoduleuserdatahelp'), 0));
     $temp->add(new admin_setting_configcheckbox('backup/backup_sche_metacourse', get_string('metacourse'), get_string('backupmetacoursehelp'), 0));
@@ -166,6 +184,6 @@ if ($hassiteconfig
             get_string('backupexecuteathelp'), array('h' => 0, 'm' => 0)));
     $temp->add(new admin_setting_configdirectory('backup/backup_sche_destination', get_string('saveto'), get_string('backupsavetohelp'), ''));
 
-    $ADMIN->add('courses', $temp);
+    $ADMIN->add('backups', $temp);
 
 } // end of speedup
index 0e7326a..753c6be 100644 (file)
@@ -236,6 +236,9 @@ class backup_controller extends backup implements loggable {
         return $this->executiontime;
     }
 
+    /**
+     * @return backup_plan
+     */
     public function get_plan() {
         return $this->plan;
     }
@@ -292,6 +295,7 @@ class backup_controller extends backup implements loggable {
 
     protected function apply_defaults() {
         $this->log('applying plan defaults', backup::LOG_DEBUG);
+        backup_controller_dbops::apply_general_config_defaults($this);
         $this->set_status(backup::STATUS_CONFIGURED);
     }
 }
index dec6bb5..cc91f45 100644 (file)
@@ -344,4 +344,40 @@ abstract class backup_controller_dbops extends backup_dbops {
             set_config('backup_release', backup::RELEASE);
         }
     }
+
+    /**
+     * Sets the controller settings default values from the backup config.
+     * 
+     * @param backup_controller $controller
+     */
+    public static function apply_general_config_defaults(backup_controller $controller) {
+        $settings = array(
+            // Config name                      => Setting name
+            'backup_general_users'              => 'users',
+            'backup_general_anonymize'          => 'anonymize',
+            'backup_general_role_assignments'   => 'role_assignments',
+            'backup_general_user_files'         => 'user_files',
+            'backup_general_activities'         => 'activities',
+            'backup_general_blocks'             => 'blocks',
+            'backup_general_filters'            => 'filters',
+            'backup_general_comments'           => 'comments',
+            'backup_general_userscompletion'    => 'userscompletion',
+            'backup_general_logs'               => 'logs',
+            'backup_general_histories'          => 'grade_histories'
+        );
+        $plan = $controller->get_plan();
+        foreach ($settings as $config=>$settingname) {
+            $value = get_config('backup', $config);
+            $locked = (get_config('backup', $config.'_locked') == true);
+            if ($plan->setting_exists($settingname)) {
+                $setting = $plan->get_setting($settingname);
+                if ($setting->get_value() != $value || 1==1) {
+                    $setting->set_value($value);
+                    if ($locked) {
+                        $setting->set_status(base_setting::LOCKED_BY_CONFIG);
+                    }
+                }
+            }
+        }
+    }
 }
index 38bf40b..557f536 100644 (file)
@@ -170,11 +170,13 @@ abstract class base_setting {
     public function set_status($status) {
         $status = $this->validate_status($status);
 
-        // If this setting is dependent on other settings first check that all
-        // of those settings are not locked
+        // If the setting is being unlocked first check whether an other settings
+        // this setting is dependent on are locked. If they are then we still don't
+        // want to lock this setting.
         if (count($this->dependenton) > 0 && $status == base_setting::NOT_LOCKED) {
             foreach ($this->dependenton as $dependency) {
-                if ($dependency->get_setting()->get_status() != base_setting::NOT_LOCKED) {
+                if ($dependency->is_locked()) {
+                    // It still needs to be locked
                     $status = base_setting::LOCKED_BY_HIERARCHY;
                     break;
                 }
@@ -192,7 +194,7 @@ abstract class base_setting {
      * Gets an array of properties for all of the dependencies that will affect
      * this setting.
      *
-     * This method returns and array rather than the dependencies in order to
+     * This method returns an array rather than the dependencies in order to
      * minimise the memory footprint of for the potentially huge recursive
      * dependency structure that we may be dealing with.
      *
@@ -216,6 +218,16 @@ abstract class base_setting {
         return $dependencies;
     }
 
+    /**
+     * Returns all of the dependencies that affect this setting.
+     * e.g. settings this setting depends on.
+     *
+     * @return array Array of setting_dependency's
+     */
+    public function get_settings_depended_on() {
+        return $this->dependenton;
+    }
+
     /**
      * Checks if there are other settings that are dependent on this setting
      *
index 7c612f3..8e04b4e 100644 (file)
@@ -142,6 +142,11 @@ abstract class setting_dependency {
      * @return array
      */
     abstract public function get_moodleform_properties();
+    /**
+     * Returns true if the dependent setting is locked.
+     * @return bool
+     */
+    abstract public function is_locked();
 }
 
 /**
@@ -169,6 +174,18 @@ class setting_dependency_disabledif_equals extends setting_dependency {
         parent::__construct($setting, $dependentsetting, $defaultvalue);
         $this->value = ($value)?(string)$value:0;
     }
+    /**
+     * Returns true if the dependent setting is locked.
+     * @return bool
+     */
+    public function is_locked() {
+        // If the setting is locked or the dependent setting should be locked then return true
+        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || $this->setting->get_value() == $this->value) {
+            return true;
+        }
+        // Else return based upon the dependent settings status
+        return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
+    }
     /**
      * Processes a value change in the primary setting
      * @param mixed $oldvalue
@@ -348,6 +365,19 @@ class setting_dependency_disabledif_not_empty extends setting_dependency_disable
         // Return true if the value has changed for the dependent setting
         return ($prevalue != $this->dependentsetting->get_value());
     }
+
+    /**
+     * Returns true if the dependent setting is locked.
+     * @return bool
+     */
+    public function is_locked() {
+        // If the setting is locked or the dependent setting should be locked then return true
+        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || !empty($value)) {
+            return true;
+        }
+        // Else return based upon the dependent settings status
+        return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
+    }
 }
 
 /**
@@ -400,4 +430,16 @@ class setting_dependency_disabledif_empty extends setting_dependency_disabledif_
         // Return true if the value has changed for the dependent setting
         return ($prevalue != $this->dependentsetting->get_value());
     }
+    /**
+     * Returns true if the dependent setting is locked.
+     * @return bool
+     */
+    public function is_locked() {
+        // If the setting is locked or the dependent setting should be locked then return true
+        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || empty($value)) {
+            return true;
+        }
+        // Else return based upon the dependent settings status
+        return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
+    }
 }
\ No newline at end of file
index c07b52a..ddc552d 100644 (file)
@@ -123,16 +123,9 @@ abstract class backup_moodleform extends moodleform {
      */
     function add_setting(backup_setting $setting, backup_task $task=null) {
 
-        // Check if the setting is locked first up
-        if ($setting->get_status() !== base_setting::NOT_LOCKED) {
-            // If it has no dependencies on other settings we can add it as a
-            // fixed setting instead
-            if (!$setting->has_dependencies_on_settings()) {
-                // Fixed setting it is!
-                return $this->add_fixed_setting($setting);
-            }
-            // Hmm possible to unlock it in the UI so disable instead.
-            $setting->get_ui()->disable();
+        // If the setting cant be changed then add it as a fixed setting.
+        if (!$setting->get_ui()->is_changeable()) {
+            return $this->add_fixed_setting($setting);
         }
 
         // First add the formatting for this setting
@@ -220,11 +213,21 @@ abstract class backup_moodleform extends moodleform {
         $settingui = $setting->get_ui();
         if ($setting->get_visibility() == backup_setting::VISIBLE) {
             $this->add_html_formatting($setting);
-            if ($setting->get_status() != backup_setting::NOT_LOCKED) {
-                $this->_form->addElement('static', 'static_'.$settingui->get_name(), $settingui->get_label(),$settingui->get_static_value().' '.$OUTPUT->pix_icon('i/unlock', get_string('locked', 'backup'), 'moodle', array('class'=>'smallicon lockedicon')));
-            } else {
-                $this->_form->addElement('static','static_'. $settingui->get_name(), $settingui->get_label(), $settingui->get_static_value());
+            switch ($setting->get_status()) {
+                case backup_setting::LOCKED_BY_PERMISSION:
+                    $icon = ' '.$OUTPUT->pix_icon('i/permissionlock', get_string('lockedbypermission', 'backup'), 'moodle', array('class'=>'smallicon lockedicon permissionlock'));
+                    break;
+                case backup_setting::LOCKED_BY_CONFIG:
+                    $icon = ' '.$OUTPUT->pix_icon('i/configlock', get_string('lockedbyconfig', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
+                    break;
+                case backup_setting::LOCKED_BY_HIERARCHY:
+                    $icon = ' '.$OUTPUT->pix_icon('i/hierarchylock', get_string('lockedbyhierarchy', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
+                    break;
+                default:
+                    $icon = '';
+                    break;
             }
+            $this->_form->addElement('static', 'static_'.$settingui->get_name(), $settingui->get_label(), $settingui->get_static_value().$icon);
             $this->_form->addElement('html', html_writer::end_tag('div'));
         }
         $this->_form->addElement('hidden', $settingui->get_name(), $settingui->get_value());
index 4d841b6..d3c3e11 100644 (file)
@@ -148,7 +148,6 @@ abstract class backup_setting_ui extends base_setting_ui {
     public function __construct(backup_setting $setting, $label = null, array $attributes = null, array $options = null) {
         parent::__construct($setting);
         // Improve the inputs name by appending the level to the name
-        if (!($setting instanceof backup_setting)) debug($setting);
         switch ($setting->get_level()) {
             case backup_setting::ROOT_LEVEL :
                 $this->name = 'root_'.$setting->get_name();
@@ -230,6 +229,41 @@ abstract class backup_setting_ui extends base_setting_ui {
         }
         return $this->label;
     }
+    /**
+     * Returns true if the setting is changeable.
+     *
+     * A setting is changeable if it meets either of the two following conditions.
+     *
+     * 1. The setting is not locked
+     * 2. The setting is locked but only by settings that are of the same level (same page)
+     *
+     * Condition 2 is really why we have this function
+     *
+     * @return bool
+     */
+    public function is_changeable() {
+        if ($this->setting->get_status() === backup_setting::NOT_LOCKED) {
+            // Its not locked so its chanegable
+            return true;
+        } else if ($this->setting->get_status() !== backup_setting::LOCKED_BY_HIERARCHY) {
+            // Its not changeable because its locked by permission or config
+            return false;
+        } else if ($this->setting->has_dependencies_on_settings()) {
+            foreach ($this->setting->get_settings_depended_on() as $dependency) {
+                if ($dependency->is_locked() && $dependency->get_setting()->get_level() !== $this->setting->get_level()) {
+                    // Its not changeable because one or more dependancies arn't
+                    // changeable.
+                   return false;
+                }
+            }
+            // Its changeable because all dependencies are changeable.
+            return true;
+        }
+        // We should never get here but if we do return false to be safe.
+        // The setting would need to be locked by hierarchy and not have any deps
+        return false;
+    }
+
 }
 
 /**
index ff34276..fc0776b 100644 (file)
@@ -41,6 +41,7 @@ if ($courseid) {
 }
 
 $context = get_context_instance_by_id($contextid, MUST_EXIST);
+$PAGE->set_context($context);
 
 $course = null;
 $cm = null;
index 81b6e55..eb13727 100755 (executable)
@@ -636,6 +636,7 @@ $string['localetext'] = 'Sitewide locale';
 $string['localstringcustomization'] = 'Local string customization';
 $string['location'] = 'Location';
 $string['locationsettings'] = 'Location settings';
+$string['locked'] = 'locked';
 $string['log'] = 'Logs';
 $string['loginhttps'] = 'Use HTTPS for logins';
 $string['loglifetime'] = 'Keep logs for';
index 190dc10..7ace6bf 100644 (file)
 $string['backupcourse'] = 'Backup course: {$a}';
 $string['backupsection'] = 'Backup course section: {$a}';
 $string['backupactivity'] = 'Backup activity: {$a}';
+$string['configgeneralactivities'] = 'Sets the default for including activities in a backup.';
+$string['configgeneralanonymize'] = 'If enabled all information pertaining to users will be anonymised by default.';
+$string['configgeneralblocks'] = 'Sets the default for including blocks in a backup.';
+$string['configgeneralcomments'] = 'Sets the default for including comments in a backup.';
+$string['configgeneralfilters'] = 'Sets the default for including filters in a backup.';
+$string['configgeneralhistories'] = 'Sets the default for including user history within a backup.';
+$string['configgenerallogs'] = 'If enabled logs will be included in backups by default.';
+$string['configgeneralroleassignments'] = 'If enabled by default roles assignments will also be backed up.';
+$string['configgeneraluserscompletion'] = 'If enabled user completion information will be included in backups by default.';
+$string['configgeneraluserfiles'] = 'Sets the default for whether user files will be included in backups.';
+$string['configgeneralusers'] = 'Sets the default for whether to include users in backups.';
 $string['coursesettings'] = 'Course settings';
 $string['currentstage1'] = 'Initial settings';
 $string['currentstage2'] = 'Schema settings';
@@ -37,10 +48,25 @@ $string['errorfilenamerequired'] = 'You must enter a valid filename for this bac
 $string['errorfilenamemustbezip'] = 'The filename you enter must be a ZIP file and have the .zip extension';
 $string['executionsuccess'] = 'Your backup completed successfully, clicking the continue button below will take you to view your backup file.';
 $string['filename'] = 'Filename';
+$string['generalactivities'] = 'Include activities';
+$string['generalanonymize'] = 'Anonymise information';
+$string['generalbackdefaults'] = 'General backup defaults';
+$string['generalblocks'] = 'Include blocks';
+$string['generalcomments'] = 'Include comments';
+$string['generalfilters'] = 'Include filters';
+$string['generalhistories'] = 'Include histories';
+$string['generallogs'] = 'Include logs';
+$string['generalroleassignments'] = 'Include role assignments';
+$string['generaluserscompletion'] = 'Include user completion information';
+$string['generaluserfiles'] = 'Include user files';
+$string['generalusers'] = 'Include users';
 $string['includesection'] = 'Include section {$a}';
 $string['includeother'] = 'Include {$a}';
 $string['includeuserinfo'] = 'Include user information';
 $string['locked'] = 'Locked';
+$string['lockedbypermission'] = 'You don\'t have sufficient permissions to change this setting';
+$string['lockedbyconfig'] = 'This setting has been locked by the default backup settings';
+$string['lockedbyhierarchy'] = 'Locked by dependencies';
 $string['onstage1action'] = 'Next';
 $string['onstage2action'] = 'Next';
 $string['onstage4action'] = 'Perform backup';
@@ -48,3 +74,4 @@ $string['onstage8action'] = 'Continue';
 $string['onstage16action'] = 'Continue';
 $string['previousstage'] = 'Previous';
 $string['rootsettings'] = 'Backup settings';
+$string['scheduledsettings'] = 'Scheduled backup settings';
\ No newline at end of file
index 7f8d29b..b526150 100644 (file)
@@ -4004,6 +4004,107 @@ EOT;
     }
 }
 
+/**
+ * Checkbox with an advanced checkbox that controls an additional $name.'_locked' config setting.
+ *
+ * This is nearly a copy/paste of admin_setting_configcheckbox_with_adv
+ *
+ * @copyright 2010 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class admin_setting_configcheckbox_with_lock extends admin_setting_configcheckbox {
+    /**
+     * Constructor
+     * @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting' for ones in config_plugins.
+     * @param string $visiblename localised
+     * @param string $description long localised info
+     * @param array $defaultsetting ('value'=>string, 'locked'=>bool)
+     * @param string $yes value used when checked
+     * @param string $no value used when not checked
+     */
+    public function __construct($name, $visiblename, $description, $defaultsetting, $yes='1', $no='0') {
+        parent::__construct($name, $visiblename, $description, $defaultsetting, $yes, $no);
+    }
+
+    /**
+     * Loads the current setting and returns array
+     *
+     * @return array Returns array value=>xx, adv=>xx
+     */
+    public function get_setting() {
+        $value = parent::get_setting();
+        $locked = $this->config_read($this->name.'_locked');
+        if (is_null($value) or is_null($locked)) {
+            return NULL;
+        }
+        return array('value' => $value, 'locked' => $locked);
+    }
+
+    /**
+     * Sets the value for the setting
+     *
+     * Sets the value for the setting to either the yes or no values
+     * of the object by comparing $data to yes
+     *
+     * @param mixed $data Gets converted to str for comparison against yes value
+     * @return string empty string or error
+     */
+    public function write_setting($data) {
+        $error = parent::write_setting($data['value']);
+        if (!$error) {
+            $value = empty($data['locked']) ? 0 : 1;
+            $this->config_write($this->name.'_locked', $value);
+        }
+        return $error;
+    }
+
+    /**
+     * Returns an XHTML checkbox field and with extra locked checkbox
+     *
+     * @param string $data If $data matches yes then checkbox is checked
+     * @param string $query
+     * @return string XHTML field
+     */
+    public function output_html($data, $query='') {
+        $defaults = $this->get_defaultsetting();
+        $defaultinfo = array();
+        if (!is_null($defaults)) {
+            if ((string)$defaults['value'] === $this->yes) {
+                $defaultinfo[] = get_string('checkboxyes', 'admin');
+            } else {
+                $defaultinfo[] = get_string('checkboxno', 'admin');
+            }
+            if (!empty($defaults['locked'])) {
+                $defaultinfo[] = get_string('locked', 'admin');
+            }
+        }
+        $defaultinfo = implode(', ', $defaultinfo);
+
+        $fullname    = $this->get_full_name();
+        $novalue     = s($this->no);
+        $yesvalue    = s($this->yes);
+        $id          = $this->get_id();
+
+        $checkboxparams = array('type'=>'checkbox', 'id'=>$id,'name'=>$fullname.'[value]', 'value'=>$yesvalue);
+        if ((string)$data['value'] === $this->yes) { // convert to strings before comparison
+            $checkboxparams['checked'] = 'checked';
+        }
+
+        $lockcheckboxparams = array('type'=>'checkbox', 'id'=>$id.'_locked','name'=>$fullname.'[locked]', 'value'=>1, 'class'=>'form-checkbox');
+        if (!empty($data['locked'])) { // convert to strings before comparison
+            $lockcheckboxparams['checked'] = 'checked';
+        }
+
+        $return  = html_writer::start_tag('div', array('class'=>'form-checkbox defaultsnext'));
+        $return .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$fullname.'[value]', 'value'=>$novalue));
+        $return .= html_writer::empty_tag('input', $checkboxparams);
+        $return .= html_writer::empty_tag('input', $lockcheckboxparams);
+        $return .= html_writer::tag('label', get_string('locked', 'admin'), array('for'=>$id.'_locked'));
+        $return .= html_writer::end_tag('div');
+        return format_admin_setting($this, $this->visiblename, $return, $this->description, true, '', $defaultinfo, $query);
+    }
+}
+
 /**
  * Dropdown menu with an advanced checkbox, that controls a additional $name.'_adv' setting.
  *
diff --git a/pix/i/configlock.gif b/pix/i/configlock.gif
new file mode 100644 (file)
index 0000000..36d1eef
Binary files /dev/null and b/pix/i/configlock.gif differ
diff --git a/pix/i/hierarchylock.gif b/pix/i/hierarchylock.gif
new file mode 100644 (file)
index 0000000..84bb424
Binary files /dev/null and b/pix/i/hierarchylock.gif differ
diff --git a/pix/i/permissionlock.gif b/pix/i/permissionlock.gif
new file mode 100644 (file)
index 0000000..b10ac74
Binary files /dev/null and b/pix/i/permissionlock.gif differ