Plugins with subplugins should not need to define their own backup steps to add subplugin information.
The designated way for plugins to add information to structure steps is through calling add_plugin_structure on a step. If a plugin defines its own subplugins, it has no way of calling add_subplugin_structure because the method is protected. Plugins added this way should not add their own structure steps to the task, although they can; they don't own the task, and the task owner might not be expecting steps to be inserted or files to be added.
Example
Consider a local plugin local_things. You can attach Things to modules, sections or courses. It has a subplugin type of thingwidget, for adding Widgets to Things. Naturally, its backup file looks a bit like this:
|
class backup_local_things_plugin extends backup_local_plugin { |
|
protected function define_module_plugin_structure() { |
$plugin = $this->get_plugin_element(); |
$pluginwrapper = new backup_nested_element($this->get_recommended_name()); |
$plugin->add_child($pluginwrapper); |
|
$widgets = new backup_nested_element('widgets'); |
$widget = new backup_nested_element('widget', ['id'], ['name', 'description']); |
$widgets->add_child($widget); |
$pluginwrapper->add_child($widgets); |
$widgets->set_source_table('things_widgets', array('cmid' => backup::VAR_MODID)); |
|
return $plugin; |
}
|
|
protected function define_section_plugin_structure() {} |
|
protected function define_course_plugin_structure() {} |
|
}
|
|
In each of these functions, it is necessary to attach subplugin information. The obvious way to do so would be
$this->step->add_subplugin_structure('thingwidget', $widget, true, 'local', 'things');
|
But this fails, with PHP Fatal error: Call to protected method backup_structure_step::add_subplugin_structure().
The only other option for a local plugin to add structures for its subplugins would be to define its own structure step class, add that step to the task from within define_plugin_structure, and then call add_subplugin_structure from that step. This has a number of obvious flaws: it would require the creation of another file, it would break the nested structure of the subplugin's data under the plugin, and it would potentially overwrite files tracked by the task, or be overwritten.
Solutions
Either add_subplugin_structure should be declared on backup_plugin or it should be made part of the public API for a structure step.