# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/backup/backup.php
--- moodle/backup/backup.php Base (1.70)
+++ moodle/backup/backup.php Locally Modified (Based On 1.70)
@@ -36,6 +36,7 @@
     $url->param('cm', $cmid);
 }
 $PAGE->set_url($url);
+$PAGE->set_pagelayout('admin');
 
 $id = $courseid;
 $cm = null;
@@ -90,7 +91,6 @@
 
 $PAGE->set_title($heading.': '.$backup->get_stage_name());
 $PAGE->set_heading($heading);
-$PAGE->set_pagelayout('admin');
 $PAGE->navbar->add($backup->get_stage_name());
 
 $renderer = $PAGE->get_renderer('core','backup');
Index: moodle/backup/moodle2/backup_root_task.class.php
--- moodle/backup/moodle2/backup_root_task.class.php Base (1.6)
+++ moodle/backup/moodle2/backup_root_task.class.php Locally Modified (Based On 1.6)
@@ -49,7 +49,7 @@
 
         // Define filename setting
         $filename = new backup_filename_setting('filename', base_setting::IS_FILENAME, 'backup.zip');
-        $filename->set_ui(get_string('filename', 'backup'), '', array('size'=>50));
+        $filename->set_ui(get_string('filename', 'backup'), 'backup.zip', array('size'=>50));
         $this->add_setting($filename);
 
         // Define users setting (keeping it on hand to define dependencies)
Index: moodle/backup/util/ui/backup_moodleform.class.php
--- moodle/backup/util/ui/backup_moodleform.class.php Base (1.8)
+++ moodle/backup/util/ui/backup_moodleform.class.php Locally Modified (Based On 1.8)
@@ -76,7 +76,7 @@
      */
     function definition() {
         $mform = $this->_form;
-        $stage = $mform->addElement('hidden', 'stage', $this->uistage->get_next_stage());
+        $stage = $mform->addElement('hidden', 'stage', $this->uistage->get_stage());
         $stage = $mform->addElement('hidden', 'backup', $this->uistage->get_backupid());
     }
     /**
@@ -84,9 +84,16 @@
      * to add elements on the fly.
      */
     function definition_after_data() {
-        $mform = $this->_form;
-        $this->add_action_buttons(get_string('cancel'), get_string('onstage'.$this->uistage->get_stage().'action', 'backup'));
+
+        $buttonarray=array();
+        if ($this->uistage->get_stage() > backup_ui::STAGE_INITIAL) {
+            $buttonarray[] = $this->_form->createElement('submit', 'previous', get_string('previousstage','backup'));
     }
+        $buttonarray[] = $this->_form->createElement('submit', 'submitbutton', get_string('onstage'.$this->uistage->get_stage().'action', 'backup'));
+        $buttonarray[] = $this->_form->createElement('cancel');
+        $this->_form->addGroup($buttonarray, 'buttonar', '', array(' '), false);
+        $this->_form->closeHeaderBefore('buttonar');
+    }
     /**
      * Closes any open divs
      */
@@ -257,4 +264,26 @@
  * Nothing to override we only need it defined so that moodleform doesn't get confused
  * between stages.
  */
-class backup_confirmation_form extends backup_moodleform {}
+class backup_confirmation_form extends backup_moodleform {
+
+    public function definition_after_data() {
+        parent::definition_after_data();
+        $this->_form->addRule('setting_root_filename', get_string('errorfilenamerequired', 'backup'), 'required');
+        $this->_form->setType('setting_root_filename', PARAM_FILE);
+    }
+
+    public function validation($data, $files) {
+        $errors = parent::validation($data, $files);
+
+        if (!array_key_exists('setting_root_filename', $errors)) {
+            if (trim($data['setting_root_filename']) == '') {
+                $errors['setting_root_filename'] = get_string('errorfilenamerequired', 'backup');
+            } else if (!preg_match('#\.zip$#i', $data['setting_root_filename'])) {
+                $errors['setting_root_filename'] = get_string('errorfilenamemustbezip', 'backup');
+            }
+        }
+
+        return $errors;
+    }
+
+}
Index: moodle/backup/util/ui/backup_ui.class.php
--- moodle/backup/util/ui/backup_ui.class.php Base (1.4)
+++ moodle/backup/util/ui/backup_ui.class.php Locally Modified (Based On 1.4)
@@ -40,6 +40,7 @@
     const STAGE_SCHEMA = 2;
     const STAGE_CONFIRMATION = 4;
     const STAGE_FINAL = 8;
+    const STAGE_COMPLETE = 16;
     /**
      * The progress of this instance of the backup ui class
      */
@@ -110,55 +111,6 @@
         return $stage;
     }
     /**
-     * This passes off processing for the current stage to the previous stage.
-     *
-     * This occurs when the current stage hasn't been completed yet
-     *
-     * @param backup_ui_stage $stage
-     * @return bool
-     */
-    public function process_previous_stage(backup_ui_stage $stage) {
-        $prevstage = $stage->get_prev_stage();
-        if ($prevstage) {
-            $prevstage = $this->initialise_stage($prevstage);
-            if ($prevstage) {
-                return $prevstage->process();
-            }
-        }
-        return false;
-    }
-    /**
-     * This magical function processes all previous stages to the provided stage
-     * given its backup_moodleform
-     *
-     * @param backup_ui_stage $stage
-     * @param backup_moodleform $form
-     * @return int The number of changes made by the user
-     */
-    public function process_all_previous_stages(backup_ui_stage $stage, backup_moodleform $form) {
-        $stages = array();
-        // First get an instance of each previous stage
-        while ($stage instanceof backup_ui_stage) {
-            $stage = $stage->get_prev_stage();
-            if ($stage) {
-                $stage = $this->initialise_stage($stage);
-                $stages[] = $stage;
-            }
-        }
-        $stages = array_reverse($stages);
-        $changes = 0;
-        // The process each stage in the correct order.
-        foreach ($stages as $stage) {
-            $outcome = $stage->process($form);
-            // Check it didn't fail
-            if ($outcome === false) {
-                throw new backup_ui_exception('backup_ui_process_all_previous_stages_failed', $stage->get_stage());
-            }
-            $changes += $outcome;
-        }
-        return $changes;
-    }
-    /**
      * This processes the current stage of the backup
      * @return bool
      */
@@ -167,8 +119,19 @@
             throw new backup_ui_exception('backupuialreadyprocessed');
         }
         $this->progress = self::PROGRESS_PROCESSED;
+
+        if (optional_param('previous', false, PARAM_BOOL) && $this->stage->get_stage() > self::STAGE_INITIAL) {
+            $this->stage = $this->initialise_stage($this->stage->get_prev_stage());
+            return false;
+        }
+
         // Process the stage
         $processoutcome = $this->stage->process();
+
+        if ($processoutcome !== false) {
+            $this->stage = $this->initialise_stage($this->stage->get_next_stage());
+        }
+
         // Process UI event after to check changes are valid
         $this->controller->process_ui_event();
         return $processoutcome;
@@ -325,7 +288,9 @@
      * @return array Array of items for the progress bar
      */
     public function get_progress_bar() {
-        $stage = self::STAGE_FINAL;
+        global $PAGE;
+        
+        $stage = self::STAGE_COMPLETE;
         $currentstage = $this->stage->get_stage();
         $items = array();
         while ($stage > 0) {
@@ -337,10 +302,11 @@
             } else if ($stage < $currentstage) {
                 $classes[] = 'backup_stage_complete';
             }
-            array_unshift($items, array(
-                'text' => get_string('currentstage'.$stage, 'backup'),
-                'class' => join(' ', $classes)
-            ));
+            $item = array('text' => strlen(decbin($stage)).'. '.get_string('currentstage'.$stage, 'backup'),'class' => join(' ', $classes));
+            if ($stage < $currentstage && $currentstage < self::STAGE_COMPLETE) {
+                $item['link'] = new moodle_url($PAGE->url, array('backup'=>$this->get_backupid(), 'stage'=>$stage));
+            }
+            array_unshift($items, $item);
             $stage = floor($stage/2);
         }
         return $items;
@@ -367,6 +333,19 @@
         return $this->controller->get_id();
     }
     /**
+     * Gets the requested setting
+     * @param string $name
+     * @return mixed
+     */
+    public function get_setting($name, $default = false) {
+        try {
+            return $this->controller->get_plan()->get_setting($name);
+        } catch (Exception $e) {
+            debugging('Failed to find the setting: '.$name, DEBUG_DEVELOPER);
+            return $default;
+        }
+    }
+    /**
      * Gets the value for the requested setting
      *
      * @param string $name
Index: moodle/backup/util/ui/backup_ui_stage.class.php
--- moodle/backup/util/ui/backup_ui_stage.class.php Base (1.2)
+++ moodle/backup/util/ui/backup_ui_stage.class.php Locally Modified (Based On 1.2)
@@ -50,6 +50,11 @@
      */
     protected $ui;
     /**
+     * The moodleform for this stage
+     * @var backup_moodleform
+     */
+    protected $stageform = null;
+    /**
      *
      * @param backup_ui $ui
      */
@@ -139,31 +144,24 @@
         $this->stage = backup_ui::STAGE_INITIAL;
         parent::__construct($ui);
     }
+
     /**
      * Processes the initial backup stage
      * @param backup_moodleform $form
      * @return int The number of changes
      */
-    public function process(backup_moodleform $form = null) {
-        // If we wern't given a form create an instance of the form for this stage
-        if (is_null($form)) {
+    public function process(backup_moodleform $m = null) {
+
             $form = $this->initialise_stage_form();
-            // Check it wasn't cancelled
+
             if ($form->is_cancelled()) {
                 $this->ui->cancel_backup();
             }
-        }
 
-        // Check if it was submit
         $data = $form->get_data();
-        if (!$data || !confirm_sesskey()) {
-            return $this->ui->process_previous_stage($this);
-        }
-
-        // Store the tasks a variable so we can iterate by reference
+        if ($data && confirm_sesskey()) {
         $tasks = $this->ui->get_backup_tasks();
         $changes = 0;
-
         foreach ($tasks as &$task) {
             // We are only interesting in the backup root task for this stage
             if ($task instanceof backup_root_task) {
@@ -183,7 +181,10 @@
         }
         // Return the number of changes the user made
         return $changes;
+        } else {
+            return false;
     }
+    }
 
     /**
      * Initialises the backup_moodleform instance for this stage
@@ -192,6 +193,7 @@
      */
     protected function initialise_stage_form() {
         global $PAGE;
+        if ($this->stageform === null) {
         $form = new backup_initial_form($this, $PAGE->url);
         // Store as a variable so we can iterate by reference
         $tasks = $this->ui->get_backup_tasks();
@@ -217,8 +219,10 @@
                 }
             }
         }
+            $this->stageform = $form;
+        }
         // Return the form
-        return $form;
+        return $this->stageform;
     }
 }
 
@@ -247,27 +251,15 @@
      * @return int The number of changes the user made
      */
     public function process(backup_moodleform $form = null) {
-        // If we wern't given a form instantiate a new form for this stage
-        if (is_null($form)) {
             $form = $this->initialise_stage_form();
             // Check it wasn't cancelled
             if ($form->is_cancelled()) {
                 $this->ui->cancel_backup();
             }
-        }
 
         // Check it has been submit
         $data = $form->get_data();
-        if (!$data || !confirm_sesskey()) {
-            return $this->ui->process_previous_stage($this);
-        }
-
-        // If this stage is the current stage first process all other stages
-        // to ensure we respect dependencies in the correct order.
-        if ($this->ui->get_stage() == $this->get_next_stage()) {
-            $this->ui->process_all_previous_stages($this, $form);
-        }
-
+        if ($data && confirm_sesskey()) {
         // Get the tasks into a var so we can iterate by reference
         $tasks = $this->ui->get_backup_tasks();
         $changes = 0;
@@ -292,7 +284,10 @@
         }
         // Return the number of changes the user made
         return $changes;
+        } else {
+            return false;
     }
+    }
     /**
      * Creates the backup_schema_form instance for this stage
      *
@@ -300,22 +295,13 @@
      */
     protected function initialise_stage_form() {
         global $PAGE;
+        if ($this->stageform === null) {
         $form = new backup_schema_form($this, $PAGE->url);
         $tasks = $this->ui->get_backup_tasks();
         $content = '';
         $courseheading = false;
         foreach ($tasks as $task) {
-            if ($task instanceof backup_root_task) {
-                // Add a root settings heading to group nicely
-                $form->add_heading('rootsettings', get_string('rootsettings', 'backup'));
-                // Iterate all settings and add them to the form as a fixed
-                // setting. We only want schema settings to be editable
-                foreach ($task->get_settings() as $setting) {
-                    if ($setting->get_name() != 'filename') {
-                        $form->add_fixed_setting($setting);
-                    }
-                }
-            } else {
+                if (!($task instanceof backup_root_task)) {
                 if (!$courseheading) {
                     // If we havn't already display a course heading to group nicely
                     $form->add_heading('coursesettings', get_string('coursesettings', 'backup'));
@@ -329,11 +315,24 @@
                 foreach ($task->get_settings() as $setting) {
                     $form->add_dependencies($setting);
                 }
+                } else if ($this->ui->enforce_changed_dependencies()) {
+                    // Only show these settings if dependencies changed them.
+                    // Add a root settings heading to group nicely
+                    $form->add_heading('rootsettings', get_string('rootsettings', 'backup'));
+                    // Iterate all settings and add them to the form as a fixed
+                    // setting. We only want schema settings to be editable
+                    foreach ($task->get_settings() as $setting) {
+                        if ($setting->get_name() != 'filename') {
+                            $form->add_fixed_setting($setting);
             }
         }
-        return $form;
     }
 }
+            $this->stageform = $form;
+        }
+        return $this->stageform;
+    }
+}
 
 /**
  * Confirmation stage
@@ -360,29 +359,14 @@
      * @return int The number of changes the user made
      */
     public function process(backup_moodleform $form = null) {
-        // If we don't have a form passed in then we need to initalise the
-        // form for this stage
-        if (is_null($form)) {
             $form = $this->initialise_stage_form();
             // Check it hasn't been cancelled
             if ($form->is_cancelled()) {
                 $this->ui->cancel_backup();
             }
-        }
 
-        // Get the data (will be false if not submit yet)
         $data = $form->get_data();
-        // If not submit or sesskey incorrect process the previous stage
-        if (!$data || !confirm_sesskey()) {
-            return $this->ui->process_previous_stage($this);
-        }
-
-        // If this stage is the current stage first process all other stages
-        // to ensure we respect dependencies in the correct order.
-        if ($this->ui->get_stage() == $this->get_stage()) {
-            $this->ui->process_all_previous_stages($this, $form);
-        }
-
+        if ($data && confirm_sesskey()) {
         // Collect into a variable so we can iterate by reference
         $tasks = $this->ui->get_backup_tasks();
         $changes = 0;
@@ -400,7 +384,10 @@
         }
         // Return the number of changes the user made
         return $changes;
+        } else {
+            return false;
     }
+    }
     /**
      * Creates the backup_confirmation_form instance this stage requires
      *
@@ -408,10 +395,25 @@
      */
     protected function initialise_stage_form() {
         global $PAGE;
+        if ($this->stageform === null) {
         // Get the form
         $form = new backup_confirmation_form($this, $PAGE->url);
         $content = '';
         $courseheading = false;
+
+            if ($setting = $this->ui->get_setting('filename')) {
+                $form->add_heading('filenamesetting', get_string('filename', 'backup'));
+                if ($setting->get_value() == 'backup.zip') {
+                    $format = $this->ui->get_backup_format();
+                    $type = $this->ui->get_backup_type();
+                    $id = $this->ui->get_controller_id();
+                    $users = $this->ui->get_setting_value('users');
+                    $anonymised = $this->ui->get_setting_value('anonymize');
+                    $setting->set_value(backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised));
+                }
+                $form->add_setting($setting);
+            }
+
         foreach ($this->ui->get_backup_tasks() as $task) {
             if ($task instanceof backup_root_task) {
                 // If its a backup root add a root settings heading to group nicely
@@ -426,21 +428,12 @@
                 // For this stage only the filename setting should be editable
                 if ($setting->get_name() != 'filename') {
                     $form->add_fixed_setting($setting);
-                } else {
-                    $value = $setting->get_value();
-                    if (empty($value)) {
-                        $format = $this->ui->get_backup_format();
-                        $type = $this->ui->get_backup_type();
-                        $id = $this->ui->get_controller_id();
-                        $users = $this->ui->get_setting_value('users');
-                        $anonymised = $this->ui->get_setting_value('anonymize');
-                        $setting->set_value(backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised));
                     }
-                    $form->add_setting($setting, $task);
                 }
             }
+            $this->stageform = $form;
         }
-        return $form;
+        return $this->stageform;
     }
 }
 
@@ -477,7 +470,7 @@
      * In this case it ALWAYS passes processing to the previous stage (confirmation)
      */
     public function process(backup_moodleform $form=null) {
-        return $this->ui->process_previous_stage($this);
+        return true;
     }
     /**
      * should NEVER be called... throws an exception
@@ -516,14 +509,19 @@
     public function __construct(backup_ui $ui, $results) {
         $this->results = $results;
         parent::__construct($ui);
+        $this->stage = backup_ui::STAGE_COMPLETE;
     }
     /**
      * Displays the completed backup stage.
      *
      * Currently this just envolves redirecting to the file browser with an
      * appropriate message.
+     *
+     * @global core_renderer $OUTPUT
      */
     public function display() {
+        global $OUTPUT;
+        
         // Get the resulting stored_file record
         $file = $this->results['backup_destination'];
         // Turn it into a url for the file browser
@@ -533,7 +531,10 @@
             'itemid' => $file->get_itemid(),
             'filepath' => $file->get_filepath()
         ));
-        // Redirect the user with a useful message
-        redirect($fileurl, get_string('executionsuccess', 'backup'), 3);
+
+        echo $OUTPUT->box_start();
+        echo get_string('executionsuccess', 'backup');
+        echo $OUTPUT->continue_button($fileurl);
+        echo $OUTPUT->box_end();
     }
 }
Index: moodle/backup/util/ui/renderer.php
--- moodle/backup/util/ui/renderer.php Base (1.1)
+++ moodle/backup/util/ui/renderer.php Locally Modified (Based On 1.1)
@@ -45,8 +45,14 @@
         foreach ($items as &$item) {
             $text = $item['text'];
             unset($item['text']);
+            if (array_key_exists('link', $item)) {
+                $link = $item['link'];
+                unset($item['link']);
+                $item = html_writer::link($link, $text, $item);
+            } else {
             $item = html_writer::tag('span', $text, $item);
         }
+        }
         return html_writer::tag('div', join(get_separator(), $items), array('class'=>'backup_progress clearfix'));
     }
     /**
Index: moodle/lang/en/backup.php
--- moodle/lang/en/backup.php Base (1.4)
+++ moodle/lang/en/backup.php Locally Modified (Based On 1.4)
@@ -33,7 +33,9 @@
 $string['currentstage8'] = 'Preform backup';
 $string['currentstage16'] = 'Complete';
 $string['dependenciesenforced'] = 'Your settings have been altered due to unmet dependencies';
-$string['executionsuccess'] = 'Your backup completed successfully, you will be redirected momentarily to the backup section for this course.';
+$string['errorfilenamerequired'] = 'You must enter a valid filename for this backup';
+$string['errorfilenamemustbezip'] = 'The filename you enter must be a ZIP file and have the .zip extension';
+$string['executionsuccess'] = 'Your backup completed successfully, clicking the continue button below will take you to view your backup file.';
 $string['filename'] = 'Filename';
 $string['includesection'] = 'Include section {$a}';
 $string['includeother'] = 'Include {$a}';
@@ -44,4 +46,5 @@
 $string['onstage4action'] = 'Perform backup';
 $string['onstage8action'] = 'Continue';
 $string['onstage16action'] = 'Continue';
+$string['previousstage'] = 'Previous';
 $string['rootsettings'] = 'Backup settings';
Index: moodle/theme/base/style/core.css
--- moodle/theme/base/style/core.css Base (1.23)
+++ moodle/theme/base/style/core.css Locally Modified (Based On 1.23)
@@ -523,10 +523,10 @@
 .path-backup .mform .grouped_settings.section_level .normal_setting {width:50%;margin:0;margin-left:50%;}
 .path-backup .notification.dependencies_enforced {text-align:center;color:#A00;font-weight:bold;}
 .path-backup .backup_progress {text-align:center;}
-.path-backup .backup_progress .backup_stage {color:#999;}
+.path-backup .backup_progress span.backup_stage {color:#999;}
 .path-backup .backup_progress .backup_stage.backup_stage_current {font-weight:bold;color:inherit;}
 .path-backup .backup_progress .backup_stage.backup_stage_next {}
-.path-backup .backup_progress .backup_stage.backup_stage_complete {color:inherit;}
+.path-backup .backup_progress span.backup_stage.backup_stage_complete {color:inherit;}
 
 
 /**
