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 protected abstract 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body