1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * This file contains the restore user interface class 19 * 20 * @package core_backup 21 * @copyright 2010 Sam Hemelryk 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 /** 26 * This is the restore user interface class 27 * 28 * The restore user interface class manages the user interface and restore for 29 * Moodle. 30 * 31 * @package core_backup 32 * @copyright 2010 Sam Hemelryk 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class restore_ui extends base_ui { 36 /** 37 * The stages of the restore user interface. 38 * Confirm the backup you are going to restore. 39 */ 40 const STAGE_CONFIRM = 1; 41 42 /** 43 * The stages of the restore user interface. 44 * Select the destination for the restore. 45 */ 46 const STAGE_DESTINATION = 2; 47 48 /** 49 * The stages of the restore user interface. 50 * Alter the setting for the restore. 51 */ 52 const STAGE_SETTINGS = 4; 53 54 /** 55 * The stages of the restore user interface. 56 * Alter and review the schema that you are going to restore. 57 */ 58 const STAGE_SCHEMA = 8; 59 60 /** 61 * The stages of the restore user interface. 62 * The final review before the restore is run. 63 */ 64 const STAGE_REVIEW = 16; 65 66 /** 67 * The stages of the restore user interface. 68 * The restore is in process right now. 69 */ 70 const STAGE_PROCESS = 32; 71 72 /** 73 * The stages of the restore user interface. 74 * The process is complete. 75 */ 76 const STAGE_COMPLETE = 64; 77 78 /** 79 * The current UI stage. 80 * @var restore_ui_stage 81 */ 82 protected $stage = null; 83 84 /** 85 * @var \core\progress\base Progress indicator (where there is no controller) 86 */ 87 protected $progressreporter = null; 88 89 /** 90 * String mappings to the above stages 91 * @var array 92 */ 93 public static $stages = array( 94 restore_ui::STAGE_CONFIRM => 'confirm', 95 restore_ui::STAGE_DESTINATION => 'destination', 96 restore_ui::STAGE_SETTINGS => 'settings', 97 restore_ui::STAGE_SCHEMA => 'schema', 98 restore_ui::STAGE_REVIEW => 'review', 99 restore_ui::STAGE_PROCESS => 'process', 100 restore_ui::STAGE_COMPLETE => 'complete' 101 ); 102 103 /** 104 * Intialises what ever stage is requested. If none are requested we check 105 * params for 'stage' and default to initial 106 * 107 * @throws restore_ui_exception for an invalid stage 108 * @param int|null $stage The desired stage to intialise or null for the default 109 * @param array $params 110 * @return restore_ui_stage_initial|restore_ui_stage_schema|restore_ui_stage_confirmation|restore_ui_stage_final 111 */ 112 protected function initialise_stage($stage = null, array $params = null) { 113 if ($stage == null) { 114 $stage = optional_param('stage', self::STAGE_CONFIRM, PARAM_INT); 115 } 116 $class = 'restore_ui_stage_'.self::$stages[$stage]; 117 if (!class_exists($class)) { 118 throw new restore_ui_exception('unknownuistage'); 119 } 120 $stage = new $class($this, $params); 121 return $stage; 122 } 123 124 /** 125 * This processes the current stage of the restore 126 * @throws restore_ui_exception if the progress is wrong. 127 * @return bool 128 */ 129 public function process() { 130 if ($this->progress >= self::PROGRESS_PROCESSED) { 131 throw new restore_ui_exception('restoreuialreadyprocessed'); 132 } 133 $this->progress = self::PROGRESS_PROCESSED; 134 135 if (optional_param('previous', false, PARAM_BOOL) && $this->stage->get_stage() > self::STAGE_CONFIRM) { 136 $this->stage = $this->initialise_stage($this->stage->get_prev_stage(), $this->stage->get_params()); 137 return false; 138 } 139 140 // Process the stage. 141 $processoutcome = $this->stage->process(); 142 if ($processoutcome !== false && !($this->get_stage() == self::STAGE_PROCESS && optional_param('substage', false, PARAM_BOOL))) { 143 $this->stage = $this->initialise_stage($this->stage->get_next_stage(), $this->stage->get_params()); 144 } 145 146 // Process UI event after to check changes are valid. 147 $this->controller->process_ui_event(); 148 return $processoutcome; 149 } 150 151 /** 152 * Returns true if the stage is independent (not requiring a restore controller) 153 * @return bool 154 */ 155 public function is_independent() { 156 return false; 157 } 158 159 /** 160 * Gets the unique ID associated with this UI 161 * @return string 162 */ 163 public function get_uniqueid() { 164 return $this->get_restoreid(); 165 } 166 167 /** 168 * Gets the restore id from the controller 169 * @return string 170 */ 171 public function get_restoreid() { 172 return $this->controller->get_restoreid(); 173 } 174 175 /** 176 * Gets the progress reporter object in use for this restore UI. 177 * 178 * IMPORTANT: This progress reporter is used only for UI progress that is 179 * outside the restore controller. The restore controller has its own 180 * progress reporter which is used for progress during the main restore. 181 * Use the restore controller's progress reporter to report progress during 182 * a restore operation, not this one. 183 * 184 * This extra reporter is necessary because on some restore UI screens, 185 * there are long-running tasks even though there is no restore controller 186 * in use. 187 * 188 * @return \core\progress\none 189 */ 190 public function get_progress_reporter() { 191 if (!$this->progressreporter) { 192 $this->progressreporter = new \core\progress\none(); 193 } 194 return $this->progressreporter; 195 } 196 197 /** 198 * Sets the progress reporter that will be returned by get_progress_reporter. 199 * 200 * @param \core\progress\base $progressreporter Progress reporter 201 */ 202 public function set_progress_reporter(\core\progress\base $progressreporter) { 203 $this->progressreporter = $progressreporter; 204 } 205 206 /** 207 * Executes the restore plan 208 * @throws restore_ui_exception if the progress or stage is wrong. 209 * @return bool 210 */ 211 public function execute() { 212 if ($this->progress >= self::PROGRESS_EXECUTED) { 213 throw new restore_ui_exception('restoreuialreadyexecuted'); 214 } 215 if ($this->stage->get_stage() < self::STAGE_PROCESS) { 216 throw new restore_ui_exception('restoreuifinalisedbeforeexecute'); 217 } 218 219 $this->controller->execute_plan(); 220 $this->progress = self::PROGRESS_EXECUTED; 221 $this->stage = new restore_ui_stage_complete($this, $this->stage->get_params(), $this->controller->get_results()); 222 return true; 223 } 224 225 /** 226 * Delete course which is created by restore process 227 */ 228 public function cleanup() { 229 global $DB; 230 $courseid = $this->controller->get_courseid(); 231 if ($this->is_temporary_course_created($courseid) && $course = $DB->get_record('course', array('id' => $courseid))) { 232 $course->deletesource = 'restore'; 233 delete_course($course, false); 234 } 235 } 236 237 /** 238 * Checks if the course is not restored fully and current controller has created it. 239 * @param int $courseid id of the course which needs to be checked 240 * @return bool 241 */ 242 protected function is_temporary_course_created($courseid) { 243 global $DB; 244 // Check if current controller instance has created new course. 245 if ($this->controller->get_target() == backup::TARGET_NEW_COURSE) { 246 $results = $DB->record_exists_sql("SELECT bc.itemid 247 FROM {backup_controllers} bc, {course} c 248 WHERE bc.operation = 'restore' 249 AND bc.type = 'course' 250 AND bc.itemid = c.id 251 AND bc.itemid = ?", 252 array($courseid) 253 ); 254 return $results; 255 } 256 return false; 257 } 258 259 /** 260 * Returns true if enforce_dependencies changed any settings 261 * @return bool 262 */ 263 public function enforce_changed_dependencies() { 264 return ($this->dependencychanges > 0); 265 } 266 267 /** 268 * Loads the restore controller if we are tracking one 269 * @param string|bool $restoreid 270 * @return string 271 */ 272 final public static function load_controller($restoreid = false) { 273 // Get the restore id optional param. 274 if ($restoreid) { 275 try { 276 // Try to load the controller with it. 277 // If it fails at this point it is likely because this is the first load. 278 $controller = restore_controller::load_controller($restoreid); 279 return $controller; 280 } catch (Exception $e) { 281 return false; 282 } 283 } 284 return $restoreid; 285 } 286 287 /** 288 * Initialised the requested independent stage 289 * 290 * @throws restore_ui_exception 291 * @param int $stage One of self::STAGE_* 292 * @param int $contextid 293 * @return restore_ui_stage_confirm|restore_ui_stage_destination 294 */ 295 final public static function engage_independent_stage($stage, $contextid) { 296 if (!($stage & self::STAGE_CONFIRM + self::STAGE_DESTINATION)) { 297 throw new restore_ui_exception('dependentstagerequested'); 298 } 299 $class = 'restore_ui_stage_'.self::$stages[$stage]; 300 if (!class_exists($class)) { 301 throw new restore_ui_exception('unknownuistage'); 302 } 303 return new $class($contextid); 304 } 305 306 /** 307 * Cancels the current restore and redirects the user back to the relevant place 308 */ 309 public function cancel_process() { 310 // Delete temporary restore course if exists. 311 if ($this->controller->get_target() == backup::TARGET_NEW_COURSE) { 312 $this->cleanup(); 313 } 314 parent::cancel_process(); 315 } 316 317 /** 318 * Gets an array of progress bar items that can be displayed through the restore renderer. 319 * @return array Array of items for the progress bar 320 */ 321 public function get_progress_bar() { 322 global $PAGE; 323 324 $stage = self::STAGE_COMPLETE; 325 $currentstage = $this->stage->get_stage(); 326 $items = array(); 327 while ($stage > 0) { 328 $classes = array('backup_stage'); 329 if (floor($stage / 2) == $currentstage) { 330 $classes[] = 'backup_stage_next'; 331 } else if ($stage == $currentstage) { 332 $classes[] = 'backup_stage_current'; 333 } else if ($stage < $currentstage) { 334 $classes[] = 'backup_stage_complete'; 335 } 336 $item = array('text' => strlen(decbin($stage)).'. '.get_string('restorestage'.$stage, 'backup'), 'class' => join(' ', $classes)); 337 if ($stage < $currentstage && $currentstage < self::STAGE_COMPLETE && $stage > self::STAGE_DESTINATION) { 338 $item['link'] = new moodle_url($PAGE->url, array('restore' => $this->get_restoreid(), 'stage' => $stage)); 339 } 340 array_unshift($items, $item); 341 $stage = floor($stage / 2); 342 } 343 return $items; 344 } 345 346 /** 347 * Gets the name of this UI 348 * @return string 349 */ 350 public function get_name() { 351 return 'restore'; 352 } 353 354 /** 355 * Gets the first stage for this UI 356 * @return int STAGE_CONFIRM 357 */ 358 public function get_first_stage_id() { 359 return self::STAGE_CONFIRM; 360 } 361 362 /** 363 * Returns true if this stage has substages of which at least one needs to be displayed 364 * @return bool 365 */ 366 public function requires_substage() { 367 return ($this->stage->has_sub_stages() && !$this->stage->process()); 368 } 369 370 /** 371 * Displays this stage 372 * 373 * @throws base_ui_exception if the progress is wrong. 374 * @param core_backup_renderer $renderer 375 * @return string HTML code to echo 376 */ 377 public function display(core_backup_renderer $renderer) { 378 if ($this->progress < self::PROGRESS_SAVED) { 379 throw new base_ui_exception('backupsavebeforedisplay'); 380 } 381 return $this->stage->display($renderer); 382 } 383 } 384 385 /** 386 * Restore user interface exception. Modelled off the restore_exception class 387 * 388 * @package core_backup 389 * @copyright 2010 Sam Hemelryk 390 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 391 */ 392 class restore_ui_exception extends base_ui_exception {}
title
Description
Body
title
Description
Body
title
Description
Body
title
Body