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
 * Provides base converter classes
20
 *
21
 * @package    core
22
 * @subpackage backup-convert
23
 * @copyright  2011 Mark Nielsen <mark@moodlerooms.com>
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
require_once($CFG->dirroot . '/backup/util/includes/convert_includes.php');
30
 
31
/**
32
 * Base converter class
33
 *
34
 * All Moodle backup converters are supposed to extend this base class.
35
 *
36
 * @throws convert_exception
37
 */
38
abstract class base_converter implements loggable {
39
 
40
    /** @var string unique identifier of this converter instance */
41
    protected $id;
42
 
43
    /** @var string the name of the directory containing the unpacked backup being converted */
44
    protected $tempdir;
45
 
46
    /** @var string the name of the directory where the backup is converted to */
47
    protected $workdir;
48
 
49
    /** @var null|base_logger logger to use during the conversion */
50
    protected $logger = null;
51
 
52
    /**
53
     * Constructor
54
     *
55
     * @param string $tempdir the relative path to the directory containing the unpacked backup to convert
56
     * @param null|base_logger logger to use during the conversion
57
     */
58
    public function __construct($tempdir, $logger = null) {
59
 
60
        $this->tempdir  = $tempdir;
61
        $this->id       = convert_helper::generate_id($tempdir);
62
        $this->workdir  = $tempdir . '_' . $this->get_name() . '_' . $this->id;
63
        $this->set_logger($logger);
64
        $this->log('instantiating '.$this->get_name().' converter '.$this->get_id(), backup::LOG_DEBUG);
65
        $this->log('conversion source directory', backup::LOG_DEBUG, $this->tempdir);
66
        $this->log('conversion target directory', backup::LOG_DEBUG, $this->workdir);
67
        $this->init();
68
    }
69
 
70
    /**
71
     * Sets the logger to use during the conversion
72
     *
73
     * @param null|base_logger $logger
74
     */
75
    public function set_logger($logger) {
76
        if (is_null($logger) or ($logger instanceof base_logger)) {
77
            $this->logger = $logger;
78
        }
79
    }
80
 
81
    /**
82
     * If the logger was set for the converter, log the message
83
     *
84
     * If the $display is enabled, the spaces in the $message text are removed
85
     * and the text is used as a string identifier in the core_backup language file.
86
     *
87
     * @see backup_helper::log()
88
     * @param string $message message text
89
     * @param int $level message level {@example backup::LOG_WARNING}
90
     * @param null|mixed $a additional information
91
     * @param null|int $depth the message depth
92
     * @param bool $display whether the message should be sent to the output, too
93
     */
94
    public function log($message, $level, $a = null, $depth = null, $display = false) {
95
        if ($this->logger instanceof base_logger) {
96
            backup_helper::log($message, $level, $a, $depth, $display, $this->logger);
97
        }
98
    }
99
 
100
    /**
101
     * Get instance identifier
102
     *
103
     * @return string the unique identifier of this converter instance
104
     */
105
    public function get_id() {
106
        return $this->id;
107
    }
108
 
109
    /**
110
     * Get converter name
111
     *
112
     * @return string the system name of the converter
113
     */
114
    public function get_name() {
115
        $parts = explode('_', get_class($this));
116
        return array_shift($parts);
117
    }
118
 
119
    /**
120
     * Converts the backup directory
121
     */
122
    public function convert() {
123
 
124
        try {
125
            $this->log('creating the target directory', backup::LOG_DEBUG);
126
            $this->create_workdir();
127
 
128
            $this->log('executing the conversion', backup::LOG_DEBUG);
129
            $this->execute();
130
 
131
            $this->log('replacing the source directory with the converted version', backup::LOG_DEBUG);
132
            $this->replace_tempdir();
133
        } catch (Exception $e) {
134
        }
135
 
136
        // clean-up stuff if needed
137
        $this->destroy();
138
 
139
        // eventually re-throw the execution exception
140
        if (isset($e) and ($e instanceof Exception)) {
141
            throw $e;
142
        }
143
    }
144
 
145
    /**
146
     * @return string the full path to the working directory
147
     */
148
    public function get_workdir_path() {
149
        global $CFG;
150
 
151
        return make_backup_temp_directory($this->workdir);
152
    }
153
 
154
    /**
155
     * @return string the full path to the directory with the source backup
156
     */
157
    public function get_tempdir_path() {
158
        global $CFG;
159
 
160
        return make_backup_temp_directory($this->tempdir);
161
    }
162
 
163
    /// public static methods //////////////////////////////////////////////////
164
 
165
    /**
166
     * Makes sure that this converter is available at this site
167
     *
168
     * This is intended for eventual PHP extensions check, environment check etc.
169
     * All checks that do not depend on actual backup data should be done here.
170
     *
171
     * @return boolean true if this converter should be considered as available
172
     */
173
    public static function is_available() {
174
        return true;
175
    }
176
 
177
    /**
178
     * Detects the format of the backup directory
179
     *
180
     * Moodle 2.x format is being detected by the core itself. The converters are
181
     * therefore supposed to detect the source format. Eventually, if the target
182
     * format os not {@link backup::FORMAT_MOODLE} then they should be able to
183
     * detect both source and target formats.
184
     *
185
     * @param string $tempdir the name of the backup directory
186
     * @return null|string null if not recognized, backup::FORMAT_xxx otherwise
187
     */
188
    public static function detect_format($tempdir) {
189
        return null;
190
    }
191
 
192
    /**
193
     * Returns the basic information about the converter
194
     *
195
     * The returned array must contain the following keys:
196
     * 'from' - the supported source format, eg. backup::FORMAT_MOODLE1
197
     * 'to'   - the supported target format, eg. backup::FORMAT_MOODLE
198
     * 'cost' - the cost of the conversion, non-negative non-zero integer
199
     */
200
    public static function description() {
201
 
202
        return array(
203
            'from'  => null,
204
            'to'    => null,
205
            'cost'  => null,
206
        );
207
    }
208
 
209
    /// end of public API //////////////////////////////////////////////////////
210
 
211
    /**
212
     * Initialize the instance if needed, called by the constructor
213
     */
214
    protected function init() {
215
    }
216
 
217
    /**
218
     * Converts the contents of the tempdir into the target format in the workdir
219
     */
220
    abstract protected function execute();
221
 
222
    /**
223
     * Prepares a new empty working directory
224
     */
225
    protected function create_workdir() {
226
 
227
        fulldelete($this->get_workdir_path());
228
        if (!check_dir_exists($this->get_workdir_path())) {
229
            throw new convert_exception('failed_create_workdir');
230
        }
231
    }
232
 
233
    /**
234
     * Replaces the source backup directory with the converted version
235
     *
236
     * If $CFG->keeptempdirectoriesonbackup is defined, the original source
237
     * source backup directory is kept for debugging purposes.
238
     */
239
    protected function replace_tempdir() {
240
        global $CFG;
241
 
242
        $tempdir = $this->get_tempdir_path();
243
 
244
        if (empty($CFG->keeptempdirectoriesonbackup)) {
245
            fulldelete($tempdir);
246
        } else {
247
            if (!rename($tempdir, $tempdir . '_' . $this->get_name() . '_' . $this->id . '_source')) {
248
                throw new convert_exception('failed_rename_source_tempdir');
249
            }
250
        }
251
 
252
        if (!rename($this->get_workdir_path(), $tempdir)) {
253
            throw new convert_exception('failed_move_converted_into_place');
254
        }
255
    }
256
 
257
    /**
258
     * Cleans up stuff after the execution
259
     *
260
     * Note that we do not know if the execution was successful or not.
261
     * An exception might have been thrown.
262
     */
263
    protected function destroy() {
264
        global $CFG;
265
 
266
        if (empty($CFG->keeptempdirectoriesonbackup)) {
267
            fulldelete($this->get_workdir_path());
268
        }
269
    }
270
}
271
 
272
/**
273
 * General convert-related exception
274
 *
275
 * @author David Mudrak <david@moodle.com>
276
 */
277
class convert_exception extends moodle_exception {
278
 
279
    /**
280
     * Constructor
281
     *
282
     * @param string $errorcode key for the corresponding error string
283
     * @param object $a extra words and phrases that might be required in the error string
284
     * @param string $debuginfo optional debugging information
285
     */
286
    public function __construct($errorcode, $a = null, $debuginfo = null) {
287
        parent::__construct($errorcode, '', '', $a, $debuginfo);
288
    }
289
}