Merge branch 'MDL-66273-MOODLE-311-v2' of https://github.com/golenkovm/moodle into...
[moodle.git] / backup / moodle2 / restore_plugin.class.php
blob31a94f50e9fd665cdf054e1f5bee6f408453f2ba
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * Defines restore_plugin class
21 * @package core_backup
22 * @subpackage moodle2
23 * @category backup
24 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 defined('MOODLE_INTERNAL') || die();
30 /**
31 * Class implementing the plugins support for moodle2 restore
33 * TODO: Finish phpdocs
35 abstract class restore_plugin {
37 /** @var string */
38 protected $plugintype;
39 /** @var string */
40 protected $pluginname;
41 /** @var string */
42 protected $connectionpoint;
43 /** @var restore_structure_step */
44 protected $step;
45 /** @var restore_course_task|restore_activity_task */
46 protected $task;
48 /**
49 * restore_plugin constructor.
51 * @param string $plugintype
52 * @param string $pluginname
53 * @param restore_structure_step $step
55 public function __construct($plugintype, $pluginname, $step) {
56 $this->plugintype = $plugintype;
57 $this->pluginname = $pluginname;
58 $this->step = $step;
59 $this->task = $step->get_task();
60 $this->connectionpoint = '';
63 public function define_plugin_structure($connectionpoint) {
64 if (!$connectionpoint instanceof restore_path_element) {
65 throw new restore_step_exception('restore_path_element_required', $connectionpoint);
68 $paths = array();
69 $this->connectionpoint = $connectionpoint;
70 $methodname = 'define_' . basename($this->connectionpoint->get_path()) . '_plugin_structure';
72 if (method_exists($this, $methodname)) {
73 if ($pluginpaths = $this->$methodname()) {
74 foreach ($pluginpaths as $path) {
75 if ($path->get_processing_object() === null && !$this->step->grouped_parent_exists($path, $paths)) {
76 $path->set_processing_object($this);
78 $paths[] = $path;
82 return $paths;
85 /**
86 * after_execute dispatcher for any restore_plugin class
88 * This method will dispatch execution to the corresponding
89 * after_execute_xxx() method when available, with xxx
90 * being the connection point of the instance, so plugin
91 * classes with multiple connection points will support
92 * multiple after_execute methods, one for each connection point
94 public function launch_after_execute_methods() {
95 // Check if the after_execute method exists and launch it
96 $afterexecute = 'after_execute_' . basename($this->connectionpoint->get_path());
97 if (method_exists($this, $afterexecute)) {
98 $this->$afterexecute();
103 * after_restore dispatcher for any restore_plugin class
105 * This method will dispatch execution to the corresponding
106 * after_restore_xxx() method when available, with xxx
107 * being the connection point of the instance, so plugin
108 * classes with multiple connection points will support
109 * multiple after_restore methods, one for each connection point
111 public function launch_after_restore_methods() {
112 // Check if the after_restore method exists and launch it
113 $afterrestore = 'after_restore_' . basename($this->connectionpoint->get_path());
114 if (method_exists($this, $afterrestore)) {
115 $this->$afterrestore();
120 * Returns one array with all the decode contents
121 * to be processed by the links decoder
123 * This method, given one plugin type, returns one
124 * array of {@link restore_decode_content} objects
125 * that will be added to the restore decoder in order
126 * to perform modifications under the plugin contents.
128 * The objects are retrieved by calling to the {@link define_decode_contents}
129 * method (when available), first in the main restore_xxxx_plugin class
130 * and later on each of the available subclasses
132 static public function get_restore_decode_contents($plugintype) {
133 $decodecontents = array();
134 // Check the requested plugintype is a valid one
135 if (!array_key_exists($plugintype, core_component::get_plugin_types($plugintype))) {
136 throw new backup_step_exception('incorrect_plugin_type', $plugintype);
138 // Check the base plugin class exists
139 $classname = 'restore_' . $plugintype . '_plugin';
140 if (!class_exists($classname)) {
141 throw new backup_step_exception('plugin_class_not_found', $classname);
143 // First, call to the define_plugin_decode_contents in the base plugin class
144 // (must exist by design in all the plugin base classes)
145 if (method_exists($classname, 'define_plugin_decode_contents')) {
146 $decodecontents = array_merge($decodecontents, call_user_func(array($classname, 'define_plugin_decode_contents')));
148 // Now, iterate over all the possible plugins available
149 // (only the needed ones have been loaded, so they will
150 // be the ones being asked here). Fetch their restore contents
151 // by calling (if exists) to their define_decode_contents() method
152 $plugins = core_component::get_plugin_list($plugintype);
153 foreach ($plugins as $plugin => $plugindir) {
154 $classname = 'restore_' . $plugintype . '_' . $plugin . '_plugin';
155 if (class_exists($classname)) {
156 if (method_exists($classname, 'define_decode_contents')) {
157 $decodecontents = array_merge($decodecontents, call_user_func(array($classname, 'define_decode_contents')));
161 return $decodecontents;
165 * Define the contents in the plugin that must be
166 * processed by the link decoder
168 static public function define_plugin_decode_contents() {
169 throw new coding_exception('define_plugin_decode_contents() method needs to be overridden in each subclass of restore_plugin');
172 // Protected API starts here
174 // restore_step/structure_step/task wrappers
176 protected function get_restoreid() {
177 if (is_null($this->task)) {
178 throw new restore_step_exception('not_specified_restore_task');
180 return $this->task->get_restoreid();
184 * To send ids pairs to backup_ids_table and to store them into paths
186 * This method will send the given itemname and old/new ids to the
187 * backup_ids_temp table, and, at the same time, will save the new id
188 * into the corresponding restore_path_element for easier access
189 * by children. Also will inject the known old context id for the task
190 * in case it's going to be used for restoring files later
192 protected function set_mapping($itemname, $oldid, $newid, $restorefiles = false, $filesctxid = null, $parentid = null) {
193 $this->step->set_mapping($itemname, $oldid, $newid, $restorefiles, $filesctxid, $parentid);
197 * Returns the latest (parent) old id mapped by one pathelement
199 protected function get_old_parentid($itemname) {
200 return $this->step->get_old_parentid($itemname);
204 * Returns the latest (parent) new id mapped by one pathelement
206 protected function get_new_parentid($itemname) {
207 return $this->step->get_new_parentid($itemname);
211 * Return the new id of a mapping for the given itemname
213 * @param string $itemname the type of item
214 * @param int $oldid the item ID from the backup
215 * @param mixed $ifnotfound what to return if $oldid wasnt found. Defaults to false
217 protected function get_mappingid($itemname, $oldid, $ifnotfound = false) {
218 return $this->step->get_mappingid($itemname, $oldid, $ifnotfound);
222 * Return the complete mapping from the given itemname, itemid
224 protected function get_mapping($itemname, $oldid) {
225 return $this->step->get_mapping($itemname, $oldid);
229 * Add all the existing file, given their component and filearea and one backup_ids itemname to match with
231 protected function add_related_files($component, $filearea, $mappingitemname, $filesctxid = null, $olditemid = null) {
232 $this->step->add_related_files($component, $filearea, $mappingitemname, $filesctxid, $olditemid);
236 * Apply course startdate offset based in original course startdate and course_offset_startdate setting
237 * Note we are using one static cache here, but *by restoreid*, so it's ok for concurrence/multiple
238 * executions in the same request
240 protected function apply_date_offset($value) {
241 return $this->step->apply_date_offset($value);
245 * Returns the value of one (task/plan) setting
247 protected function get_setting_value($name) {
248 if (is_null($this->task)) {
249 throw new restore_step_exception('not_specified_restore_task');
251 return $this->task->get_setting_value($name);
254 // end of restore_step/structure_step/task wrappers
257 * Simple helper function that returns the name for the restore_path_element
258 * It's not mandatory to use it but recommended ;-)
260 protected function get_namefor($name = '') {
261 $name = $name !== '' ? '_' . $name : '';
262 return $this->plugintype . '_' . $this->pluginname . $name;
266 * Simple helper function that returns the base (prefix) of the path for the restore_path_element
267 * Useful if we used get_recommended_name() in backup. It's not mandatory to use it but recommended ;-)
269 protected function get_pathfor($path = '') {
270 $path = trim($path, '/') !== '' ? '/' . trim($path, '/') : '';
271 return $this->connectionpoint->get_path() . '/' .
272 'plugin_' . $this->plugintype . '_' .
273 $this->pluginname . '_' . basename($this->connectionpoint->get_path()) . $path;
277 * Get the task we are part of.
279 * @return restore_activity_task|restore_course_task the task.
281 protected function get_task() {
282 return $this->task;