Skip to content

Commit

Permalink
MDL-80191 backup: add subsections to restore form
Browse files Browse the repository at this point in the history
This commit adds two new levels to the restore course structure form:
subsection (a delegated section that belongs to a course module) and
subactivity (a course module in a subsection).

Restore form can only use information from the backup file. To allow
activities to know if they are inside a subsection, the backup now
incorporates an "insubsection" attribute. This attribute is used only
for the form display but not for the restore logic.
  • Loading branch information
ferranrecio committed Jul 1, 2024
1 parent c997f91 commit b5f14e8
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 19 deletions.
8 changes: 5 additions & 3 deletions backup/moodle2/backup_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -2136,9 +2136,11 @@ protected function define_structure() {

$activities = new backup_nested_element('activities');

$activity = new backup_nested_element('activity', null, array(
'moduleid', 'sectionid', 'modulename', 'title',
'directory'));
$activity = new backup_nested_element(
'activity',
null,
['moduleid', 'sectionid', 'modulename', 'title', 'directory', 'insubsection']
);

$sections = new backup_nested_element('sections');

Expand Down
21 changes: 19 additions & 2 deletions backup/moodle2/restore_activity_task.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ public function get_moduleid() {
return $this->moduleid;
}

/**
* Return if the activity is inside a subsection.
*
* @return bool
*/
public function is_in_subsection(): bool {
return !empty($this->info->insubsection);
}

/**
* Returns the old course module id (cmid of activity which will be restored)
*
Expand Down Expand Up @@ -312,7 +321,11 @@ protected function add_activity_included_setting(string $settingprefix): activit
// - sectionincluded setting (if exists).
$settingname = $settingprefix . 'included';

$activityincluded = new restore_activity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
if ($this->is_in_subsection()) {
$activityincluded = new restore_subactivity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
} else {
$activityincluded = new restore_activity_generic_setting($settingname, base_setting::IS_BOOLEAN, true);
}

$activityincluded->get_ui()->set_icon(new image_icon('monologo', get_string('pluginname', $this->modulename),
$this->modulename, ['class' => 'iconlarge icon-post ml-1']));
Expand Down Expand Up @@ -351,7 +364,11 @@ protected function add_activity_userinfo_setting(
$defaultvalue = true;
}

$activityuserinfo = new restore_activity_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
if ($this->is_in_subsection()) {
$activityuserinfo = new restore_subactivity_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
} else {
$activityuserinfo = new restore_activity_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
}

if (!$defaultvalue) {
// This is a bit hacky, but if there is no user data to restore, then
Expand Down
78 changes: 65 additions & 13 deletions backup/moodle2/restore_section_task.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@ public function get_taskbasepath() {
return $this->get_basepath() . '/sections/section_' . $this->info->sectionid;
}

/**
* Get the course module that is delegating this section.
*
* @return int|null the course module id that is delegating this section
*/
public function get_delegated_cm(): ?int {
if (!isset($this->info->parentcmid) || empty($this->info->parentcmid)) {
return null;
}
return intval($this->info->parentcmid);
}

/**
* Get the delegated activity modname if any.
*
* @return string|null the modname of the delegated activity
*/
public function get_modname(): ?string {
if (!isset($this->info->modname) || empty($this->info->modname)) {
return null;
}
return $this->info->modname;
}

public function set_sectionid($sectionid) {
$this->sectionid = $sectionid;
}
Expand Down Expand Up @@ -169,20 +193,35 @@ protected function add_section_included_setting(string $settingprefix): section_
// Define sectionincluded (to decide if the whole task must be really executed).
$settingname = $settingprefix . 'included';

$sectionincluded = new restore_section_included_setting($settingname, base_setting::IS_BOOLEAN, true);

if (is_number($this->info->title)) {
$label = get_string('includesection', 'backup', $this->info->title);
} elseif (empty($this->info->title)) { // Don't throw error if title is empty, gracefully continue restore.
$this->log(
'Section title missing in backup for section id ' . $this->info->sectionid,
backup::LOG_WARNING,
$this->name
);
$label = get_string('unnamedsection', 'backup');
$delegatedcmid = $this->get_delegated_cm();
if ($delegatedcmid) {
$sectionincluded = new restore_subsection_included_setting($settingname, base_setting::IS_BOOLEAN, true);
// Subsections depends on the parent activity included setting.
$settingname = $this->get_modname() . '_' . $delegatedcmid . '_included';
if ($this->plan->setting_exists($settingname)) {
$cmincluded = $this->plan->get_setting($settingname);
$cmincluded->add_dependency(
$sectionincluded,
);
}
$label = get_string('subsectioncontent', 'backup');
} else {
$label = $this->info->title;
$sectionincluded = new restore_section_included_setting($settingname, base_setting::IS_BOOLEAN, true);

if (is_number($this->info->title)) {
$label = get_string('includesection', 'backup', $this->info->title);
} else if (empty($this->info->title)) { // Don't throw error if title is empty, gracefully continue restore.
$this->log(
'Section title missing in backup for section id ' . $this->info->sectionid,
backup::LOG_WARNING,
$this->name
);
$label = get_string('unnamedsection', 'backup');
} else {
$label = $this->info->title;
}
}

$sectionincluded->get_ui()->set_label($label);
$this->add_setting($sectionincluded);

Expand All @@ -209,7 +248,20 @@ protected function add_section_userinfo_setting(
$defaultvalue = true;
}

$sectionuserinfo = new restore_section_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
$delegatedcmid = $this->get_delegated_cm();
if ($delegatedcmid) {
$sectionuserinfo = new restore_subsection_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
// Subsections depends on the parent activity included setting.
$settingname = $this->get_modname() . '_' . $delegatedcmid . '_userinfo';
if ($this->plan->setting_exists($settingname)) {
$cmincluded = $this->plan->get_setting($settingname);
$cmincluded->add_dependency(
$sectionuserinfo,
);
}
} else {
$sectionuserinfo = new restore_section_userinfo_setting($settingname, base_setting::IS_BOOLEAN, $defaultvalue);
}

if (!$defaultvalue) {
// This is a bit hacky, but if there is no user data to restore, then
Expand Down
68 changes: 68 additions & 0 deletions backup/moodle2/restore_settingslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,39 @@ class restore_section_included_setting extends restore_section_generic_setting {
*/
class restore_section_userinfo_setting extends restore_section_generic_setting {}

/**
* Subsection base class (delegated section).
*/
class restore_subsection_generic_setting extends restore_section_generic_setting {
/**
* Class constructor.
*
* @param string $name Name of the setting
* @param string $vtype Type of the setting, for example base_setting::IS_TEXT
* @param mixed $value Value of the setting
* @param bool $visibility Is the setting visible in the UI, for example base_setting::VISIBLE
* @param int $status Status of the setting with regards to the locking, for example base_setting::NOT_LOCKED
*/
public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) {
parent::__construct($name, $vtype, $value, $visibility, $status);
$this->level = self::SUBSECTION_LEVEL;
}
}

/**
* Setting to define if one subsection is included or no.
*
* Activities _included settings depend of them if available.
*/
class restore_subsection_included_setting extends restore_subsection_generic_setting {
}

/**
* Subsection backup setting to control if section will include
* user information or no, depends of @restore_users_setting.
*/
class restore_subsection_userinfo_setting extends restore_subsection_generic_setting {
}

// Activity backup settings

Expand All @@ -243,6 +276,41 @@ class restore_activity_included_setting extends restore_activity_generic_setting
*/
class restore_activity_userinfo_setting extends restore_activity_generic_setting {}

/**
* Generic subactivity setting to pass various settings between tasks and steps
*/
class restore_subactivity_generic_setting extends restore_activity_generic_setting {
/**
* Class constructor.
*
* @param string $name Name of the setting
* @param string $vtype Type of the setting, for example base_setting::IS_TEXT
* @param mixed $value Value of the setting
* @param bool $visibility Is the setting visible in the UI, for example base_setting::VISIBLE
* @param int $status Status of the setting with regards to the locking, for example base_setting::NOT_LOCKED
*/
public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) {
parent::__construct($name, $vtype, $value, $visibility, $status);
$this->level = self::SUBACTIVITY_LEVEL;
}
}

/**
* Subactivity backup setting to control if activity will be included or no.
*
* Depends of restore_activities_setting and optionally parent section included setting.
*/
class restore_subactivity_included_setting extends restore_subactivity_generic_setting {
}

/**
* Subactivity backup setting to control if activity will include user information.
*
* Depends of restore_users_setting.
*/
class restore_subactivity_userinfo_setting extends restore_subactivity_generic_setting {
}

/**
* root setting to control if restore will create content bank content or no
*/
Expand Down
4 changes: 3 additions & 1 deletion backup/util/dbops/backup_controller_dbops.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ private static function get_activity_backup_information($task) {
'sectionid' => $task->get_sectionid(),
'modulename' => $task->get_modulename(),
'title' => $task->get_name(),
'directory' => 'activities/' . $task->get_modulename() . '_' . $task->get_moduleid());
'directory' => 'activities/' . $task->get_modulename() . '_' . $task->get_moduleid(),
'insubsection' => ($task->is_in_subsection()) ? 1 : '',
);

// Now get activity settings
// Calculate prefix to find valid settings
Expand Down

0 comments on commit b5f14e8

Please sign in to comment.