Merge branch 'wip-mdl-57328' of https://github.com/rajeshtaneja/moodle
[moodle.git] / backup / converter / convertlib.php
blobef37f5ea3ca15b9388af193cff608ff8caf42d78
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 * Provides base converter classes
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
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->dirroot . '/backup/util/includes/convert_includes.php');
31 /**
32 * Base converter class
34 * All Moodle backup converters are supposed to extend this base class.
36 * @throws convert_exception
38 abstract class base_converter implements loggable {
40 /** @var string unique identifier of this converter instance */
41 protected $id;
43 /** @var string the name of the directory containing the unpacked backup being converted */
44 protected $tempdir;
46 /** @var string the name of the directory where the backup is converted to */
47 protected $workdir;
49 /** @var null|base_logger logger to use during the conversion */
50 protected $logger = null;
52 /**
53 * Constructor
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
58 public function __construct($tempdir, $logger = null) {
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();
70 /**
71 * Sets the logger to use during the conversion
73 * @param null|base_logger $logger
75 public function set_logger($logger) {
76 if (is_null($logger) or ($logger instanceof base_logger)) {
77 $this->logger = $logger;
81 /**
82 * If the logger was set for the converter, log the message
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.
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
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);
101 * Get instance identifier
103 * @return string the unique identifier of this converter instance
105 public function get_id() {
106 return $this->id;
110 * Get converter name
112 * @return string the system name of the converter
114 public function get_name() {
115 $parts = explode('_', get_class($this));
116 return array_shift($parts);
120 * Converts the backup directory
122 public function convert() {
124 try {
125 $this->log('creating the target directory', backup::LOG_DEBUG);
126 $this->create_workdir();
128 $this->log('executing the conversion', backup::LOG_DEBUG);
129 $this->execute();
131 $this->log('replacing the source directory with the converted version', backup::LOG_DEBUG);
132 $this->replace_tempdir();
133 } catch (Exception $e) {
136 // clean-up stuff if needed
137 $this->destroy();
139 // eventually re-throw the execution exception
140 if (isset($e) and ($e instanceof Exception)) {
141 throw $e;
146 * @return string the full path to the working directory
148 public function get_workdir_path() {
149 global $CFG;
151 return "$CFG->tempdir/backup/$this->workdir";
155 * @return string the full path to the directory with the source backup
157 public function get_tempdir_path() {
158 global $CFG;
160 return "$CFG->tempdir/backup/$this->tempdir";
163 /// public static methods //////////////////////////////////////////////////
166 * Makes sure that this converter is available at this site
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.
171 * @return boolean true if this converter should be considered as available
173 public static function is_available() {
174 return true;
178 * Detects the format of the backup directory
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.
185 * @param string $tempdir the name of the backup directory
186 * @return null|string null if not recognized, backup::FORMAT_xxx otherwise
188 public static function detect_format($tempdir) {
189 return null;
193 * Returns the basic information about the converter
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
200 public static function description() {
202 return array(
203 'from' => null,
204 'to' => null,
205 'cost' => null,
209 /// end of public API //////////////////////////////////////////////////////
212 * Initialize the instance if needed, called by the constructor
214 protected function init() {
218 * Converts the contents of the tempdir into the target format in the workdir
220 protected abstract function execute();
223 * Prepares a new empty working directory
225 protected function create_workdir() {
227 fulldelete($this->get_workdir_path());
228 if (!check_dir_exists($this->get_workdir_path())) {
229 throw new convert_exception('failed_create_workdir');
234 * Replaces the source backup directory with the converted version
236 * If $CFG->keeptempdirectoriesonbackup is defined, the original source
237 * source backup directory is kept for debugging purposes.
239 protected function replace_tempdir() {
240 global $CFG;
242 if (empty($CFG->keeptempdirectoriesonbackup)) {
243 fulldelete($this->get_tempdir_path());
244 } else {
245 if (!rename($this->get_tempdir_path(), $this->get_tempdir_path() . '_' . $this->get_name() . '_' . $this->id . '_source')) {
246 throw new convert_exception('failed_rename_source_tempdir');
250 if (!rename($this->get_workdir_path(), $this->get_tempdir_path())) {
251 throw new convert_exception('failed_move_converted_into_place');
256 * Cleans up stuff after the execution
258 * Note that we do not know if the execution was successful or not.
259 * An exception might have been thrown.
261 protected function destroy() {
262 global $CFG;
264 if (empty($CFG->keeptempdirectoriesonbackup)) {
265 fulldelete($this->get_workdir_path());
271 * General convert-related exception
273 * @author David Mudrak <david@moodle.com>
275 class convert_exception extends moodle_exception {
278 * Constructor
280 * @param string $errorcode key for the corresponding error string
281 * @param object $a extra words and phrases that might be required in the error string
282 * @param string $debuginfo optional debugging information
284 public function __construct($errorcode, $a = null, $debuginfo = null) {
285 parent::__construct($errorcode, '', '', $a, $debuginfo);