Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
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.
14
//
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/>.
17
 
18
/**
19
 * Defines restore_plugin class
20
 *
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
26
 */
27
 
28
defined('MOODLE_INTERNAL') || die();
29
 
30
/**
31
 * Class implementing the plugins support for moodle2 restore
32
 *
33
 * TODO: Finish phpdocs
34
 */
35
abstract class restore_plugin {
36
 
37
    /** @var string */
38
    protected $plugintype;
39
    /** @var string */
40
    protected $pluginname;
41
    /** @var restore_path_element */
42
    protected $connectionpoint;
43
    /** @var restore_structure_step */
44
    protected $step;
45
    /** @var restore_course_task|restore_activity_task */
46
    protected $task;
47
 
48
    /**
49
     * restore_plugin constructor.
50
     *
51
     * @param string $plugintype
52
     * @param string $pluginname
53
     * @param restore_structure_step $step
54
     */
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 = '';
61
    }
62
 
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);
66
        }
67
 
68
        $paths = array();
69
        $this->connectionpoint = $connectionpoint;
70
        $methodname = 'define_' . basename($this->connectionpoint->get_path()) . '_plugin_structure';
71
 
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);
77
                    }
78
                    $paths[] = $path;
79
                }
80
            }
81
        }
82
        return $paths;
83
    }
84
 
85
    /**
86
     * after_execute dispatcher for any restore_plugin class
87
     *
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
93
     */
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();
99
        }
100
    }
101
 
102
    /**
103
     * after_restore dispatcher for any restore_plugin class
104
     *
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
110
     */
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();
116
        }
117
    }
118
 
119
    /**
120
     * Returns one array with all the decode contents
121
     * to be processed by the links decoder
122
     *
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.
127
     *
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
131
     */
132
    public static 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);
137
        }
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);
142
        }
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')));
147
        }
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')));
158
                }
159
            }
160
        }
161
        return $decodecontents;
162
    }
163
 
164
    /**
165
     * Define the contents in the plugin that must be
166
     * processed by the link decoder
167
     */
168
    public static 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');
170
    }
171
 
172
// Protected API starts here
173
 
174
// restore_step/structure_step/task wrappers
175
 
176
    protected function get_restoreid() {
177
        if (is_null($this->task)) {
178
            throw new restore_step_exception('not_specified_restore_task');
179
        }
180
        return $this->task->get_restoreid();
181
    }
182
 
183
    /**
184
     * To send ids pairs to backup_ids_table and to store them into paths
185
     *
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
191
     */
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);
194
    }
195
 
196
    /**
197
     * Returns the latest (parent) old id mapped by one pathelement
198
     */
199
    protected function get_old_parentid($itemname) {
200
        return $this->step->get_old_parentid($itemname);
201
    }
202
 
203
    /**
204
     * Returns the latest (parent) new id mapped by one pathelement
205
     */
206
    protected function get_new_parentid($itemname) {
207
        return $this->step->get_new_parentid($itemname);
208
    }
209
 
210
    /**
211
     * Return the new id of a mapping for the given itemname
212
     *
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
216
     */
217
    protected function get_mappingid($itemname, $oldid, $ifnotfound = false) {
218
        return $this->step->get_mappingid($itemname, $oldid, $ifnotfound);
219
    }
220
 
221
    /**
222
     * Return the complete mapping from the given itemname, itemid
223
     */
224
    protected function get_mapping($itemname, $oldid) {
225
        return $this->step->get_mapping($itemname, $oldid);
226
    }
227
 
228
    /**
229
     * Add all the existing file, given their component and filearea and one backup_ids itemname to match with
230
     */
231
    protected function add_related_files($component, $filearea, $mappingitemname, $filesctxid = null, $olditemid = null) {
232
        $this->step->add_related_files($component, $filearea, $mappingitemname, $filesctxid, $olditemid);
233
    }
234
 
235
    /**
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
239
     */
240
    protected function apply_date_offset($value) {
241
        return $this->step->apply_date_offset($value);
242
    }
243
 
244
    /**
245
     * Returns the value of one (task/plan) setting
246
     */
247
    protected function get_setting_value($name) {
248
        if (is_null($this->task)) {
249
            throw new restore_step_exception('not_specified_restore_task');
250
        }
251
        return $this->task->get_setting_value($name);
252
    }
253
 
254
// end of restore_step/structure_step/task wrappers
255
 
256
    /**
257
     * Simple helper function that returns the name for the restore_path_element
258
     * It's not mandatory to use it but recommended ;-)
259
     */
260
    protected function get_namefor($name = '') {
261
        $name = $name !== '' ? '_' . $name : '';
262
        return $this->plugintype . '_' . $this->pluginname . $name;
263
    }
264
 
265
    /**
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 ;-)
268
     */
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;
274
    }
275
 
276
    /**
277
     * Get the task we are part of.
278
     *
279
     * @return restore_activity_task|restore_course_task the task.
280
     */
281
    protected function get_task() {
282
        return $this->task;
283
    }
284
}