From 5ef6f97f478d52a5b9117efdc32b45ee9fb00cb4 Mon Sep 17 00:00:00 2001 From: Matt Sammarco Date: Wed, 12 Nov 2014 17:24:40 +1100 Subject: [PATCH] MDL-18177 availability: Excluding group members availability info If setting was not enabled when backing up, exclude the availability information of group members. --- availability/classes/info.php | 34 ++++++++++++++++--- availability/classes/tree.php | 16 ++++++--- availability/classes/tree_node.php | 23 ++++++++++++- .../condition/group/classes/condition.php | 7 ++++ .../condition/grouping/classes/condition.php | 7 ++++ availability/upgrade.txt | 7 ++++ backup/moodle2/restore_stepslib.php | 4 +-- 7 files changed, 87 insertions(+), 11 deletions(-) diff --git a/availability/classes/info.php b/availability/classes/info.php index 95363c9653e..afd1d40b013 100644 --- a/availability/classes/info.php +++ b/availability/classes/info.php @@ -311,17 +311,25 @@ abstract class info { * @param int $courseid Target course id * @param \base_logger $logger Logger for any warnings * @param int $dateoffset Date offset to be added to any dates (0 = none) + * @param \base_task $task Restore task */ - public function update_after_restore($restoreid, $courseid, \base_logger $logger, $dateoffset) { + public function update_after_restore($restoreid, $courseid, \base_logger $logger, + $dateoffset, \base_task $task) { $tree = $this->get_availability_tree(); // Set static data for use by get_restore_date_offset function. - self::$restoreinfo = array('restoreid' => $restoreid, 'dateoffset' => $dateoffset); + self::$restoreinfo = array('restoreid' => $restoreid, 'dateoffset' => $dateoffset, + 'task' => $task); $changed = $tree->update_after_restore($restoreid, $courseid, $logger, $this->get_thing_name()); if ($changed) { // Save modified data. - $structure = $tree->save(); - $this->set_in_database(json_encode($structure)); + if ($tree->is_empty()) { + // If the tree is empty, but the tree has changed, remove this condition. + $this->set_in_database(null); + } else { + $structure = $tree->save(); + $this->set_in_database(json_encode($structure)); + } } } @@ -343,6 +351,24 @@ abstract class info { return self::$restoreinfo['dateoffset']; } + /** + * Gets the restore task (specifically, the task that calls the + * update_after_restore method) for the current restore. + * + * @param string $restoreid Restore identifier + * @return \base_task Restore task + * @throws coding_exception If not in a restore (or not in that restore) + */ + public static function get_restore_task($restoreid) { + if (!self::$restoreinfo) { + throw new coding_exception('Only valid during restore'); + } + if (self::$restoreinfo['restoreid'] !== $restoreid) { + throw new coding_exception('Data not available for that restore id'); + } + return self::$restoreinfo['task']; + } + /** * Obtains the name of the item (cm_info or section_info, at present) that * this is controlling availability of. Name should be formatted ready diff --git a/availability/classes/tree.php b/availability/classes/tree.php index e6383ed7615..88493207a48 100644 --- a/availability/classes/tree.php +++ b/availability/classes/tree.php @@ -663,10 +663,18 @@ class tree extends tree_node { public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) { $changed = false; - foreach ($this->children as $child) { - $thischanged = $child->update_after_restore($restoreid, $courseid, - $logger, $name); - $changed = $changed || $thischanged; + foreach ($this->children as $index => $child) { + if ($child->include_after_restore($restoreid, $courseid, $logger, $name, + info::get_restore_task($restoreid))) { + $thischanged = $child->update_after_restore($restoreid, $courseid, + $logger, $name); + $changed = $changed || $thischanged; + } else { + unset($this->children[$index]); + unset($this->showchildren[$index]); + $this->showchildren = array_values($this->showchildren); + $changed = true; + } } return $changed; } diff --git a/availability/classes/tree_node.php b/availability/classes/tree_node.php index 0c3e0e47a9c..2b1ddc082be 100644 --- a/availability/classes/tree_node.php +++ b/availability/classes/tree_node.php @@ -82,13 +82,34 @@ abstract class tree_node { */ public abstract function save(); + /** + * Checks whether this node should be included after restore or not. The + * node may be removed depending on restore settings, which you can get from + * the $task object. + * + * By default nodes are still included after restore. + * + * @param string $restoreid Restore ID + * @param int $courseid ID of target course + * @param \base_logger $logger Logger for any warnings + * @param string $name Name of this item (for use in warning messages) + * @param \base_task $task Current restore task + * @return bool True if there was any change + */ + public function include_after_restore($restoreid, $courseid, \base_logger $logger, $name, + \base_task $task) { + return true; + } + /** * Updates this node after restore, returning true if anything changed. * The default behaviour is simply to return false. If there is a problem * with the update, $logger can be used to output a warning. * * Note: If you need information about the date offset, call - * \core_availability\info::get_restore_date_offset($restoreid). + * \core_availability\info::get_restore_date_offset($restoreid). For + * information on the restoring task and its settings, call + * \core_availability\info::get_restore_task($restoreid). * * @param string $restoreid Restore ID * @param int $courseid ID of target course diff --git a/availability/condition/group/classes/condition.php b/availability/condition/group/classes/condition.php index 2445cdc963f..3057a110260 100644 --- a/availability/condition/group/classes/condition.php +++ b/availability/condition/group/classes/condition.php @@ -127,6 +127,13 @@ class condition extends \core_availability\condition { return $this->groupid ? '#' . $this->groupid : 'any'; } + public function include_after_restore($restoreid, $courseid, \base_logger $logger, + $name, \base_task $task) { + // Include this condition only if we are including groups in restore, or + // if it's a generic 'any group' one. + return !$this->groupid || $task->get_setting_value('groups'); + } + public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) { global $DB; if (!$this->groupid) { diff --git a/availability/condition/grouping/classes/condition.php b/availability/condition/grouping/classes/condition.php index e0b59976ba8..fa3b31fa0fb 100644 --- a/availability/condition/grouping/classes/condition.php +++ b/availability/condition/grouping/classes/condition.php @@ -158,6 +158,13 @@ class condition extends \core_availability\condition { } } + public function include_after_restore($restoreid, $courseid, \base_logger $logger, + $name, \base_task $task) { + // Include this condition only if we are including groups in restore, or + // if it's a generic 'same activity' one. + return !$this->groupingid || $task->get_setting_value('groups'); + } + public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) { global $DB; if (!$this->groupingid) { diff --git a/availability/upgrade.txt b/availability/upgrade.txt index 1d2dc4622b6..92d3b8d4eee 100644 --- a/availability/upgrade.txt +++ b/availability/upgrade.txt @@ -2,6 +2,13 @@ This files describes API changes in /availability/*. The information here is intended only for developers. +=== 2.9 === + +* Condition plugins can now implement a new include_after_restore function to + indicate that they should be removed during the restore process. (This is + implemented so that group and grouping conditions are removed if groups are + not restored.) + === 2.8 === * There is a new API function in the info_module/info_section objects (and diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index c8dcaa9c25e..d779cfacf5b 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -683,7 +683,7 @@ class restore_update_availability extends restore_execution_step { if (!is_null($section->availability)) { $info = new \core_availability\info_section($section); $info->update_after_restore($this->get_restoreid(), - $this->get_courseid(), $this->get_logger(), $dateoffset); + $this->get_courseid(), $this->get_logger(), $dateoffset, $this->task); } } $rs->close(); @@ -703,7 +703,7 @@ class restore_update_availability extends restore_execution_step { if (!is_null($cm->availability)) { $info = new \core_availability\info_module($cm); $info->update_after_restore($this->get_restoreid(), - $this->get_courseid(), $this->get_logger(), $dateoffset); + $this->get_courseid(), $this->get_logger(), $dateoffset, $this->task); } } $rs->close();