backup MDL-22142 This is the user interface for backups, several minor/cosmetic issue...
[moodle.git] / backup / util / ui / backup_ui_stage.class.php
CommitLineData
1904e9b3
SH
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 * Backup user interface stages
20 *
21 * This file contains the classes required to manage the stages that make up the
22 * backup user interface.
23 * These will be primarily operated a {@see backup_ui} instance.
24 *
25 * @package moodlecore
26 * @copyright 2010 Sam Hemelryk
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 */
29
30/**
31 * Abstract stage class
32 *
33 * This class should be extended by all backup stages (a requirement of many backup ui functions).
34 * Each stage must then define two abstract methods
35 * - process : To process the stage
36 * - initialise_stage_form : To get a backup_moodleform instance for the stage
37 *
38 * @copyright 2010 Sam Hemelryk
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41abstract class backup_ui_stage {
42 /**
43 * The current stage
44 * @var int
45 */
46 protected $stage = backup_ui::STAGE_INITIAL;
47 /**
48 * The backuck UI object
49 * @var backup_ui
50 */
51 protected $ui;
52 /**
53 *
54 * @param backup_ui $ui
55 */
56 public function __construct(backup_ui $ui) {
57 $this->ui = $ui;
58 }
59 /**
60 * The current stage
61 * @return int
62 */
63 final public function get_stage() {
64 return $this->stage;
65 }
66 /**
67 * The next stage
68 * @return int
69 */
70 final public function get_next_stage() {
71 return floor($this->stage*2);
72 }
73 /**
74 * The previous stage
75 * @return int
76 */
77 final public function get_prev_stage() {
78 return floor($this->stage/2);
79 }
80 /**
81 * The name of this stage
82 * @return string
83 */
84 final public function get_name() {
85 return get_string('currentstage'.$this->stage,'backup');
86 }
87 /**
88 * The backup id from the backup controller
89 * @return string
90 */
91 final public function get_backupid() {
92 return $this->ui->get_backupid();
93 }
94 /**
95 * Displays the stage.
96 *
97 * By default this involves instantiating the form for the stage and the calling
98 * it to display. Remember this is a moodleform instance so it will print
99 * rather than return.
100 */
101 public function display() {
102 $form = $this->initialise_stage_form();
103 $form->display();
104 }
105 /**
106 * Processes the stage.
107 *
108 * This must be overridden by every stage as it will be different for every stage
109 *
110 * @abstract
111 * @param backup_moodleform|null $form
112 */
113 abstract public function process(backup_moodleform $form=null);
114 /**
115 * Creates an instance of the correct moodleform properly populated and all
116 * dependencies instantiated
117 *
118 * @abstract
119 * @return backup_moodleform
120 */
121 abstract protected function initialise_stage_form();
122}
123
124/**
125 * Class representing the initial stage of a backup.
126 *
127 * In this stage the user is required to set the root level settings.
128 *
129 * @copyright 2010 Sam Hemelryk
130 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
131 */
132class backup_ui_stage_initial extends backup_ui_stage {
133
134 /**
135 * Initial backup stage constructor
136 * @param backup_ui $ui
137 */
138 public function __construct(backup_ui $ui) {
139 $this->stage = backup_ui::STAGE_INITIAL;
140 parent::__construct($ui);
141 }
142 /**
143 * Processes the initial backup stage
144 * @param backup_moodleform $form
145 * @return int The number of changes
146 */
147 public function process(backup_moodleform $form = null) {
148 // If we wern't given a form create an instance of the form for this stage
149 if (is_null($form)) {
150 $form = $this->initialise_stage_form();
151 // Check it wasn't cancelled
152 if ($form->is_cancelled()) {
153 $this->ui->cancel_backup();
154 }
155 }
156
157 // Check if it was submit
158 $data = $form->get_data();
159 if (!$data || !confirm_sesskey()) {
160 return $this->ui->process_previous_stage($this);
161 }
162
163 // Store the tasks a variable so we can iterate by reference
164 $tasks = $this->ui->get_backup_tasks();
165 $changes = 0;
166
167 foreach ($tasks as &$task) {
168 // We are only interesting in the backup root task for this stage
169 if ($task instanceof backup_root_task) {
170 // Get all settings into a var so we can iterate by reference
171 $settings = $task->get_settings();
172 foreach ($settings as &$setting) {
173 $name = $setting->get_ui_name();
174 if (isset($data->$name) && $data->$name != $setting->get_value()) {
175 $setting->set_value($data->$name);
176 $changes++;
177 } else if (!isset($data->$name) && $setting->get_ui_type() == backup_setting::UI_HTML_CHECKBOX && $setting->get_value()) {
178 $setting->set_value(0);
179 $changes++;
180 }
181 }
182 }
183 }
184 // Return the number of changes the user made
185 return $changes;
186 }
187
188 /**
189 * Initialises the backup_moodleform instance for this stage
190 *
191 * @return backup_initial_form
192 */
193 protected function initialise_stage_form() {
194 global $PAGE;
195 $form = new backup_initial_form($this, $PAGE->url);
196 // Store as a variable so we can iterate by reference
197 $tasks = $this->ui->get_backup_tasks();
198 // Iterate all tasks by reference
199 foreach ($tasks as &$task) {
200 // For the initial stage we are only interested in the root settings
201 if ($task instanceof backup_root_task) {
202 $form->add_heading('rootsettings', get_string('rootsettings', 'backup'));
203 $settings = $task->get_settings();
204 // First add all settings except the filename setting
205 foreach ($settings as &$setting) {
206 if ($setting->get_name() == 'filename') {
207 continue;
208 }
209 $form->add_setting($setting, $task);
210 }
211 // Then add all dependencies
212 foreach ($settings as &$setting) {
213 if ($setting->get_name() == 'filename') {
214 continue;
215 }
216 $form->add_dependencies($setting);
217 }
218 }
219 }
220 // Return the form
221 return $form;
222 }
223}
224
225/**
226 * Schema stage of backup process
227 *
228 * During the schema stage the user is required to set the settings that relate
229 * to the area that they are backing up as well as its children.
230 *
231 * @copyright 2010 Sam Hemelryk
232 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
233 */
234class backup_ui_stage_schema extends backup_ui_stage {
235 /**
236 * Schema stage constructor
237 * @param backup_moodleform $ui
238 */
239 public function __construct(backup_ui $ui) {
240 $this->stage = backup_ui::STAGE_SCHEMA;
241 parent::__construct($ui);
242 }
243 /**
244 * Processes the schema stage
245 *
246 * @param backup_moodleform|null $form
247 * @return int The number of changes the user made
248 */
249 public function process(backup_moodleform $form = null) {
250 // If we wern't given a form instantiate a new form for this stage
251 if (is_null($form)) {
252 $form = $this->initialise_stage_form();
253 // Check it wasn't cancelled
254 if ($form->is_cancelled()) {
255 $this->ui->cancel_backup();
256 }
257 }
258
259 // Check it has been submit
260 $data = $form->get_data();
261 if (!$data || !confirm_sesskey()) {
262 return $this->ui->process_previous_stage($this);
263 }
264
265 // If this stage is the current stage first process all other stages
266 // to ensure we respect dependencies in the correct order.
267 if ($this->ui->get_stage() == $this->get_next_stage()) {
268 $this->ui->process_all_previous_stages($this, $form);
269 }
270
271 // Get the tasks into a var so we can iterate by reference
272 $tasks = $this->ui->get_backup_tasks();
273 $changes = 0;
274 // Iterate all tasks by reference
275 foreach ($tasks as &$task) {
276 // We are only interested in schema settings
277 if (!($task instanceof backup_root_task)) {
278 // Store as a variable so we can iterate by reference
279 $settings = $task->get_settings();
280 // Iterate by reference
281 foreach ($settings as &$setting) {
282 $name = $setting->get_ui_name();
283 if (isset($data->$name) && $data->$name != $setting->get_value()) {
284 $setting->set_value($data->$name);
285 $changes++;
286 } else if (!isset($data->$name) && $setting->get_ui_type() == backup_setting::UI_HTML_CHECKBOX && $setting->get_value()) {
287 $setting->set_value(0);
288 $changes++;
289 }
290 }
291 }
292 }
293 // Return the number of changes the user made
294 return $changes;
295 }
296 /**
297 * Creates the backup_schema_form instance for this stage
298 *
299 * @return backup_schema_form
300 */
301 protected function initialise_stage_form() {
302 global $PAGE;
303 $form = new backup_schema_form($this, $PAGE->url);
304 $tasks = $this->ui->get_backup_tasks();
305 $content = '';
306 $courseheading = false;
307 foreach ($tasks as $task) {
308 if ($task instanceof backup_root_task) {
309 // Add a root settings heading to group nicely
310 $form->add_heading('rootsettings', get_string('rootsettings', 'backup'));
311 // Iterate all settings and add them to the form as a fixed
312 // setting. We only want schema settings to be editable
313 foreach ($task->get_settings() as $setting) {
314 if ($setting->get_name() != 'filename') {
315 $form->add_fixed_setting($setting);
316 }
317 }
318 } else {
319 if (!$courseheading) {
320 // If we havn't already display a course heading to group nicely
321 $form->add_heading('coursesettings', get_string('coursesettings', 'backup'));
322 $courseheading = true;
323 }
324 // First add each setting
325 foreach ($task->get_settings() as $setting) {
326 $form->add_setting($setting, $task);
327 }
328 // The add all the dependencies
329 foreach ($task->get_settings() as $setting) {
330 $form->add_dependencies($setting);
331 }
332 }
333 }
334 return $form;
335 }
336}
337
338/**
339 * Confirmation stage
340 *
341 * On this stage the user reviews the setting for the backup and can change the filename
342 * of the file that will be generated.
343 *
344 * @copyright 2010 Sam Hemelryk
345 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
346 */
347class backup_ui_stage_confirmation extends backup_ui_stage {
348 /**
349 * Constructs the stage
350 * @param backup_ui $ui
351 */
352 public function __construct($ui) {
353 $this->stage = backup_ui::STAGE_CONFIRMATION;
354 parent::__construct($ui);
355 }
356 /**
357 * Processes the confirmation stage
358 *
359 * @param backup_moodleform $form
360 * @return int The number of changes the user made
361 */
362 public function process(backup_moodleform $form = null) {
363 // If we don't have a form passed in then we need to initalise the
364 // form for this stage
365 if (is_null($form)) {
366 $form = $this->initialise_stage_form();
367 // Check it hasn't been cancelled
368 if ($form->is_cancelled()) {
369 $this->ui->cancel_backup();
370 }
371 }
372
373 // Get the data (will be false if not submit yet)
374 $data = $form->get_data();
375 // If not submit or sesskey incorrect process the previous stage
376 if (!$data || !confirm_sesskey()) {
377 return $this->ui->process_previous_stage($this);
378 }
379
380 // If this stage is the current stage first process all other stages
381 // to ensure we respect dependencies in the correct order.
382 if ($this->ui->get_stage() == $this->get_stage()) {
383 $this->ui->process_all_previous_stages($this, $form);
384 }
385
386 // Collect into a variable so we can iterate by reference
387 $tasks = $this->ui->get_backup_tasks();
388 $changes = 0;
389 // Iterate each task by reference
390 foreach ($tasks as &$task) {
391 if ($task instanceof backup_root_task) {
392 // At this stage all we are interested in is the filename setting
393 $setting = $task->get_setting('filename');
394 $name = $setting->get_ui_name();
395 if (isset($data->$name) && $data->$name != $setting->get_value()) {
396 $setting->set_value($data->$name);
397 $changes++;
398 }
399 }
400 }
401 // Return the number of changes the user made
402 return $changes;
403 }
404 /**
405 * Creates the backup_confirmation_form instance this stage requires
406 *
407 * @return backup_confirmation_form
408 */
409 protected function initialise_stage_form() {
410 global $PAGE;
411 // Get the form
412 $form = new backup_confirmation_form($this, $PAGE->url);
413 $content = '';
414 $courseheading = false;
415 foreach ($this->ui->get_backup_tasks() as $task) {
416 if ($task instanceof backup_root_task) {
417 // If its a backup root add a root settings heading to group nicely
418 $form->add_heading('rootsettings', get_string('rootsettings', 'backup'));
419 } else if (!$courseheading) {
420 // we havn't already add a course heading
421 $form->add_heading('coursesettings', get_string('coursesettings', 'backup'));
422 $courseheading = true;
423 }
424 // Iterate all settings, doesnt need to happen by reference
425 foreach ($task->get_settings() as $setting) {
426 // For this stage only the filename setting should be editable
427 if ($setting->get_name() != 'filename') {
428 $form->add_fixed_setting($setting);
429 } else {
430 $form->add_setting($setting, $task);
431 }
432 }
433 }
434 return $form;
435 }
436}
437
438/**
439 * Final stage of backup
440 *
441 * This stage is special in that it is does not make use of a form. The reason for
442 * this is the order of procession of backup at this stage.
443 * The processesion is:
444 * 1. The final stage will be intialise.
445 * 2. The confirmation stage will be processed.
446 * 3. The backup will be executed
447 * 4. The complete stage will be loaded by execution
448 * 5. The complete stage will be displayed
449 *
450 * This highlights that we neither need a form nor a display method for this stage
451 * we simply need to process.
452 *
453 * @copyright 2010 Sam Hemelryk
454 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
455 */
456class backup_ui_stage_final extends backup_ui_stage {
457 /**
458 * Constructs the final stage
459 * @param backup_ui $ui
460 */
461 public function __construct(backup_ui $ui) {
462 $this->stage = backup_ui::STAGE_FINAL;
463 parent::__construct($ui);
464 }
465 /**
466 * Processes the final stage.
467 *
468 * In this case it ALWAYS passes processing to the previous stage (confirmation)
469 */
470 public function process(backup_moodleform $form=null) {
471 return $this->ui->process_previous_stage($this);
472 }
473 /**
474 * should NEVER be called... throws an exception
475 */
476 protected function initialise_stage_form() {
477 throw new backup_ui_exception('backup_ui_must_execute_first');
478 }
479 /**
480 * should NEVER be called... throws an exception
481 */
482 public function display() {
483 throw new backup_ui_exception('backup_ui_must_execute_first');
484 }
485}
486
487/**
488 * The completed backup stage
489 *
490 * At this stage everything is done and the user will be redirected to view the
491 * backup file in the file browser.
492 *
493 * @copyright 2010 Sam Hemelryk
494 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
495 */
496class backup_ui_stage_complete extends backup_ui_stage_final {
497 /**
498 * The results of the backup execution
499 * @var array
500 */
501 protected $results;
502 /**
503 * Constructs the complete backup stage
504 * @param backup_ui $ui
505 * @param array $results
506 */
507 public function __construct(backup_ui $ui, $results) {
508 $this->results = $results;
509 parent::__construct($ui);
510 }
511 /**
512 * Displays the completed backup stage.
513 *
514 * Currently this just envolves redirecting to the file browser with an
515 * appropriate message.
516 */
517 public function display() {
518 // Get the resulting stored_file record
519 $file = $this->results['backup_destination'];
520 // Turn it into a url for the file browser
521 $fileurl = new moodle_url('/files/index.php', array(
522 'contextid' => $file->get_contextid(),
523 'filearea' => $file->get_filearea(),
524 'itemid' => $file->get_itemid(),
525 'filepath' => $file->get_filepath()
526 ));
527 // Redirect the user with a useful message
528 redirect($fileurl, get_string('executionsuccess', 'backup'), 3);
529 }
530}