Added course format backup/restore support

From: Brandon Turner <brandont@thinkwell.com>

Added the ability to backup/restore custom course formats similar to how
modules are currently implemented.  Course formats must take the following
steps if they wish to support backup/restore (they are not required to):

1) Implement callback_xxx_uses_backup() in course/format/xxx/lib.php.  In lieu
   of course format support in plugin_supports() this returns true if the
   format supports backup/restore.  If the method isn't implemented, false is
   assumed.
2) Add a course/format/xxx/backup/moodle2 folder
3) Add backup_format_xxx_task.class.php in the backup/moodle2 folder.  For more
   information, see the task files used by the activity modules.
4) Add restore_format_xxx_task.class.php in the backup/moodle2 folder.  For
   more information, see the task files used by the activity modules.
---
 backup/controller/backup_controller.class.php      |    6 +
 backup/import.php                                  |    1 
 backup/moodle2/backup_format_task.class.php        |  110 ++++++++++++++++++++
 backup/moodle2/backup_plan_builder.class.php       |   17 +++
 backup/moodle2/backup_stepslib.php                 |   37 +++++++
 backup/moodle2/restore_format_task.class.php       |   94 +++++++++++++++++
 backup/moodle2/restore_plan_builder.class.php      |   22 ++++
 backup/moodle2/restore_stepslib.php                |   20 ++++
 backup/restore.php                                 |    1 
 backup/restorefile.php                             |    1 
 .../util/dbops/backup_controller_dbops.class.php   |   28 +++++
 backup/util/factories/backup_factory.class.php     |   16 +++
 backup/util/factories/restore_factory.class.php    |    7 +
 backup/util/helper/backup_general_helper.class.php |    9 ++
 .../restore_moodlexml_parser_processor.class.php   |    1 
 backup/util/includes/restore_includes.php          |    1 
 course/lib.php                                     |   15 +++
 17 files changed, 384 insertions(+), 2 deletions(-)
 create mode 100644 backup/moodle2/backup_format_task.class.php
 create mode 100644 backup/moodle2/restore_format_task.class.php

diff --git a/backup/controller/backup_controller.class.php b/backup/controller/backup_controller.class.php
index e4f61aa..c4de187 100644
--- a/backup/controller/backup_controller.class.php
+++ b/backup/controller/backup_controller.class.php
@@ -47,6 +47,7 @@ class backup_controller extends backup implements loggable {
     protected $type;   // Type of backup (activity, section, course)
     protected $id;     // Course/section/course_module id to backup
     protected $courseid; // courseid where the id belongs to
+    protected $courseformat; // name of course format
     protected $format; // Format of backup (moodle, imscc)
     protected $interactive; // yes/no
     protected $mode;   // Purpose of the backup (default settings)
@@ -69,6 +70,7 @@ class backup_controller extends backup implements loggable {
         $this->type = $type;
         $this->id   = $id;
         $this->courseid = backup_controller_dbops::get_courseid_from_type_id($this->type, $this->id);
+        $this->courseformat = backup_controller_dbops::get_course_format_from_courseid($this->courseid);
         $this->format = $format;
         $this->interactive = $interactive;
         $this->mode = $mode;
@@ -215,6 +217,10 @@ class backup_controller extends backup implements loggable {
         return $this->courseid;
     }
 
+    public function get_courseformat() {
+        return $this->courseformat;
+    }
+
     public function get_format() {
         return $this->format;
     }
diff --git a/backup/import.php b/backup/import.php
index 751269b..9ff6e52 100644
--- a/backup/import.php
+++ b/backup/import.php
@@ -5,6 +5,7 @@ require_once('../config.php');
 require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_plan_builder.class.php');
 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
+require_once($CFG->dirroot . '/backup/moodle2/restore_plan_builder.class.php');
 require_once($CFG->dirroot . '/backup/util/ui/import_extensions.php');
 
 // The courseid we are importing to
diff --git a/backup/moodle2/backup_format_task.class.php b/backup/moodle2/backup_format_task.class.php
new file mode 100644
index 0000000..cb8cdb5
--- /dev/null
+++ b/backup/moodle2/backup_format_task.class.php
@@ -0,0 +1,110 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package moodlecore
+ * @subpackage backup-moodle2
+ * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * abstract course format task that provides all the properties and common tasks to be performed
+ * when a course format is being backup
+ *
+ * TODO: Finish phpdocs
+ */
+abstract class backup_format_task extends backup_task {
+
+    protected $courseid;
+    protected $formatname;
+
+    /**
+     * Constructor - instantiates one object of this class
+     */
+    public function __construct($name, $courseid, $plan = null) {
+
+        $this->courseid   = $courseid;
+        $this->formatname = $name;
+
+        parent::__construct($name, $plan);
+    }
+
+    public function get_courseid() {
+        return $this->courseid;
+    }
+
+    public function get_formatname() {
+        return $this->formatname;
+    }
+
+    /**
+     * Format tasks have their own directory to write files
+     */
+    public function get_taskbasepath() {
+        return $this->get_basepath() . '/format';
+    }
+
+    /**
+     * Create all the steps that will be part of this task
+     */
+    public function build() {
+
+        // Add some extra settings that related processors are going to need
+        $this->add_setting(new backup_activity_generic_setting(backup::VAR_COURSEID, base_setting::IS_INTEGER, $this->get_courseid()));
+
+        // Create the format directory
+        $this->add_step(new create_taskbasepath_directory('create_format_directory'));
+
+        // Annotate the groups used in already annotated groupings
+        $this->add_step(new backup_annotate_groups_from_groupings('annotate_groups'));
+
+        // Here we add all the common steps for any format and, in the point of interest
+        // we call to define_my_steps() is order to get the particular ones inserted in place.
+        $this->define_my_steps();
+
+        // At the end, mark it as built
+        $this->built = true;
+    }
+
+// Protected API starts here
+
+    /**
+     * Define the common setting that any backup activity will have
+     */
+    protected function define_settings() {
+
+        $this->define_my_settings();
+    }
+
+    /**
+     * Define (add) particular settings that each format can have
+     */
+    abstract protected function define_my_settings();
+
+    /**
+     * Define (add) particular steps that each format can have
+     */
+    abstract protected function define_my_steps();
+
+    /**
+     * Code the transformations to perform in the format in
+     * order to get transportable (encoded) links
+     */
+    abstract static public function encode_content_links($content);
+
+}
diff --git a/backup/moodle2/backup_plan_builder.class.php b/backup/moodle2/backup_plan_builder.class.php
index 9066338..21e20c8 100644
--- a/backup/moodle2/backup_plan_builder.class.php
+++ b/backup/moodle2/backup_plan_builder.class.php
@@ -28,6 +28,7 @@ require_once($CFG->dirroot . '/backup/moodle2/backup_root_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_activity_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_section_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_course_task.class.php');
+require_once($CFG->dirroot . '/backup/moodle2/backup_format_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_final_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_block_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/backup_default_block_task.class.php');
@@ -57,6 +58,15 @@ foreach ($blocks as $block => $blockdir) {
     }
 }
 
+// Load all the format tasks for moodle2 format
+$formats = get_plugin_list('format');
+foreach ($formats as $format => $formatdir) {
+    $taskpath = $formatdir . '/backup/moodle2/backup_format_' . $format . '_task.class.php';
+    if (course_format_uses_backup($format) && file_exists($taskpath)) {
+        require_once($taskpath);
+    }
+}
+
 /**
  * Abstract class defining the static method in charge of building the whole
  * backup plan, based in @backup_controller preferences.
@@ -152,11 +162,18 @@ abstract class backup_plan_builder {
     static protected function build_course_plan($controller, $id) {
 
         $plan = $controller->get_plan();
+        $courseformat = $controller->get_courseformat();
 
         // Add the course task, responsible for outputting
         // all the course related information
         $plan->add_task(backup_factory::get_backup_course_task($controller->get_format(), $id));
 
+        // Backup the course format if supported
+        // TODO: When plugin_supports covers course formats, use it here
+        if($courseformat && course_format_uses_backup($courseformat)) {
+            $plan->add_task(backup_factory::get_backup_format_task($controller->get_format(), $id));
+        }
+
         // For the given course, add as many section tasks as necessary
         $sections = backup_plan_dbops::get_sections_from_courseid($id);
         foreach ($sections as $section) {
diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php
index e46634f..bf75e51 100644
--- a/backup/moodle2/backup_stepslib.php
+++ b/backup/moodle2/backup_stepslib.php
@@ -330,6 +330,33 @@ class backup_course_structure_step extends backup_structure_step {
 }
 
 /**
+ * Abstract structure step, parent of all the format structure steps. Used to wrap the
+ * format structure definition within the main <format ...> tag.
+ */
+abstract class backup_format_structure_step extends backup_structure_step {
+
+    /**
+     * Wraps any format backup structure within the common 'format' element
+     */
+    protected function prepare_format_structure($formatstructure) {
+
+        // Create the wrap element
+        $format = new backup_nested_element('format', array('name'));
+
+        // Build the tree
+        $format->add_child($formatstructure);
+
+        // Set the source
+        $formatarr = array((object)array(
+            'name'   => $this->task->get_name()));
+
+        $format->set_source_array($formatarr);
+
+        return $format;
+    }
+}
+
+/**
  * structure step that will generate the enrolments.xml file for the given course
  */
 class backup_enrolments_structure_step extends backup_structure_step {
@@ -1244,7 +1271,7 @@ class backup_main_structure_step extends backup_structure_step {
 
         $detail = new backup_nested_element('detail', array('backup_id'), array(
             'type', 'format', 'interactive', 'mode',
-            'execution', 'executiontime'));
+            'execution', 'executiontime', 'courseformat'));
 
         $contents = new backup_nested_element('contents');
 
@@ -1262,6 +1289,9 @@ class backup_main_structure_step extends backup_structure_step {
         $course = new backup_nested_element('course', null, array(
             'courseid', 'title', 'directory'));
 
+        $format = new backup_nested_element('format', null, array(
+            'name', 'directory'));
+
         $settings = new backup_nested_element('settings');
 
         $setting = new backup_nested_element('setting', null, array(
@@ -1286,6 +1316,9 @@ class backup_main_structure_step extends backup_structure_step {
         if (!empty($cinfo['course'])) {
             $contents->add_child($course);
         }
+        if (!empty($cinfo['format'])) {
+            $contents->add_child($format);
+        }
 
         $information->add_child($settings);
         $settings->add_child($setting);
@@ -1303,6 +1336,8 @@ class backup_main_structure_step extends backup_structure_step {
 
         $course->set_source_array($cinfo['course']);
 
+        $format->set_source_array($cinfo['format']);
+
         $setting->set_source_array($sinfo);
 
         // Prepare some information to be sent to main moodle_backup.xml file
diff --git a/backup/moodle2/restore_format_task.class.php b/backup/moodle2/restore_format_task.class.php
new file mode 100644
index 0000000..2577b19
--- /dev/null
+++ b/backup/moodle2/restore_format_task.class.php
@@ -0,0 +1,94 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package moodlecore
+ * @subpackage backup-moodle2
+ * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * abstract course format task that provides all the properties and common tasks to be performed
+ * when a course format is being restored
+ *
+ * TODO: Finish phpdocs
+ */
+abstract class restore_format_task extends restore_task {
+
+    protected $info; // info related to courseformat gathered from backup file
+
+    /**
+     * Constructor - instantiates one object of this class
+     */
+    public function __construct($name, $info, $plan = null) {
+        $this->info   = $info;
+        parent::__construct($name, $plan);
+    }
+
+    /**
+     * Format tasks have their own directory to write files
+     */
+    public function get_taskbasepath() {
+        return $this->get_basepath() . '/format';
+    }
+
+    /**
+     * Create all the steps that will be part of this task
+     */
+    public function build() {
+
+        // Here we add all the common steps for any format and, in the point of interest
+        // we call to define_my_steps() is order to get the particular ones inserted in place.
+        $this->define_my_steps();
+
+        // At the end, mark it as built
+        $this->built = true;
+    }
+
+// Protected API starts here
+
+    /**
+     * Define the common setting that any backup activity will have
+     */
+    protected function define_settings() {
+
+        $this->define_my_settings();
+    }
+
+    /**
+     * Define (add) particular settings that each format can have
+     */
+    abstract protected function define_my_settings();
+
+    /**
+     * Define (add) particular steps that each format can have
+     */
+    abstract protected function define_my_steps();
+
+    /**
+     * Define the contents in the format that must be
+     * processed by the link decoder
+     */
+    abstract static public function define_decode_contents();
+
+    /**
+     * Define the decoding rules for links belonging
+     * to the format to be executed by the link decoder
+     */
+    abstract static public function define_decode_rules();
+}
diff --git a/backup/moodle2/restore_plan_builder.class.php b/backup/moodle2/restore_plan_builder.class.php
index 3f09689..4219ca7 100644
--- a/backup/moodle2/restore_plan_builder.class.php
+++ b/backup/moodle2/restore_plan_builder.class.php
@@ -26,6 +26,7 @@ defined('MOODLE_INTERNAL') || die();
 
 require_once($CFG->dirroot . '/backup/moodle2/restore_root_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/restore_course_task.class.php');
+require_once($CFG->dirroot . '/backup/moodle2/restore_format_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/restore_section_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/restore_activity_task.class.php');
 require_once($CFG->dirroot . '/backup/moodle2/restore_final_task.class.php');
@@ -55,6 +56,15 @@ foreach ($blocks as $block => $blockdir) {
     }
 }
 
+// Load all the format tasks for moodle2 format
+$formats = get_plugin_list('format');
+foreach ($formats as $format => $formatdir) {
+    $taskpath = $formatdir . '/backup/moodle2/restore_format_' . $format . '_task.class.php';
+    if (course_format_uses_backup($format) && file_exists($taskpath)) {
+        require_once($taskpath);
+    }
+}
+
 /**
  * Abstract class defining the static method in charge of building the whole
  * restore plan, based in @restore_controller preferences.
@@ -168,6 +178,18 @@ abstract class restore_plan_builder {
         $task = restore_factory::get_restore_course_task($info->course, $courseid);
         $plan->add_task($task);
 
+        // Restore the course format if supported
+        if(isset($info->courseformat) && isset($info->courseformat->name))
+        {
+            $courseformat = $info->courseformat->name;
+            // TODO: When plugin_supports covers course formats, use it here
+            if(course_format_uses_backup($courseformat)) {
+                $plan->add_task(restore_factory::get_restore_format_task($info->courseformat, $courseformat));
+            } else {
+                // TODO: Debug information about course format not supported
+            }
+        }
+
         // For the given course path, add as many block tasks as necessary
         // TODO: Add blocks, we need to introspect xml here
         $blocks = backup_general_helper::get_blocks_from_path($task->get_taskbasepath());
diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php
index 386d8f4..ed332f0 100644
--- a/backup/moodle2/restore_stepslib.php
+++ b/backup/moodle2/restore_stepslib.php
@@ -1004,6 +1004,26 @@ class restore_course_structure_step extends restore_structure_step {
 }
 
 
+/**
+ * Abstract structure step, parent of all the format structure steps. Used to support the
+ * main <format ...> tag and process it
+ */
+abstract class restore_format_structure_step extends restore_structure_step {
+
+    protected function prepare_format_structure($paths) {
+
+        $paths[] = new restore_path_element('format', '/format');
+
+        return $paths;
+    }
+
+    protected function process_format($data) {
+        $data = (object)$data;
+        // TODO!
+    }
+}
+
+
 /*
  * Structure step that will read the roles.xml file (at course/activity/block levels)
  * containig all the role_assignments and overrides for that context. If corresponding to
diff --git a/backup/restore.php b/backup/restore.php
index 084ab1f..44a972e 100644
--- a/backup/restore.php
+++ b/backup/restore.php
@@ -3,6 +3,7 @@
 
 require_once('../config.php');
 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
+require_once($CFG->dirroot . '/backup/moodle2/restore_plan_builder.class.php');
 
 $contextid   = required_param('contextid', PARAM_INT);
 $stage      = optional_param('stage', restore_ui::STAGE_CONFIRM, PARAM_INT);
diff --git a/backup/restorefile.php b/backup/restorefile.php
index e9b406a..ec2a0ed 100755
--- a/backup/restorefile.php
+++ b/backup/restorefile.php
@@ -25,6 +25,7 @@
 require_once('../config.php');
 require_once(dirname(__FILE__) . '/restorefile_form.php');
 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
+require_once($CFG->dirroot . '/backup/moodle2/restore_plan_builder.class.php');
 
 // current context
 $contextid = required_param('contextid', PARAM_INT);
diff --git a/backup/util/dbops/backup_controller_dbops.class.php b/backup/util/dbops/backup_controller_dbops.class.php
index cc7c631..a1b07ad 100644
--- a/backup/util/dbops/backup_controller_dbops.class.php
+++ b/backup/util/dbops/backup_controller_dbops.class.php
@@ -157,6 +157,15 @@ abstract class backup_controller_dbops extends backup_dbops {
     }
 
     /**
+     * Given one course id, return the associated course format
+     */
+    public static function get_course_format_from_courseid($courseid) {
+        global $DB;
+
+        return $DB->get_field('course', 'format', array('id' => $courseid));
+    }
+
+    /**
      * Given one activity task, return the activity information and related settings
      * Used by get_moodle_backup_information()
      */
@@ -259,6 +268,17 @@ abstract class backup_controller_dbops extends backup_dbops {
         return array($contentinfo, $settingsinfo);
     }
 
+    private static function get_format_backup_information($task) {
+
+        $contentinfo = array(
+            'name'      => $task->get_formatname(),
+            'directory' => 'format');
+
+        $settingsinfo = array();
+
+        return array($contentinfo, $settingsinfo);
+    }
+
     /**
      * Given one root task, return the course information and related settings
      * Used by get_moodle_backup_information()
@@ -303,12 +323,14 @@ abstract class backup_controller_dbops extends backup_dbops {
         $detailsinfo['executiontime'] = $bc->get_executiontime();
         $detailsinfo['userid'] = $bc->get_userid();
         $detailsinfo['courseid'] = $bc->get_courseid();
+        $detailsinfo['courseformat'] = $bc->get_courseformat();
 
 
         // Init content placeholders
         $contentsinfo['activities'] = array();
         $contentsinfo['sections']   = array();
         $contentsinfo['course']     = array();
+        $contentsinfo['format']     = array();
 
         // Contents info (extract information from tasks)
         foreach ($bc->get_plan()->get_tasks() as $task) {
@@ -335,6 +357,12 @@ abstract class backup_controller_dbops extends backup_dbops {
                 $contentsinfo['course'][] = $contentinfo;
                 $settingsinfo = array_merge($settingsinfo, $settings);
 
+            } else if ($task instanceof backup_format_task) { // Course format task
+
+                list($contentinfo, $settings) = self::get_format_backup_information($task);
+                $contentsinfo['format'][] = $contentinfo;
+                $settingsinfo = array_merge($settingsinfo, $settings);
+
             } else if ($task instanceof backup_root_task) { // Root task
 
                 list($contentinfo, $settings) = self::get_root_backup_information($task);
diff --git a/backup/util/factories/backup_factory.class.php b/backup/util/factories/backup_factory.class.php
index 9655e87..872dda4 100644
--- a/backup/util/factories/backup_factory.class.php
+++ b/backup/util/factories/backup_factory.class.php
@@ -157,6 +157,22 @@ abstract class backup_factory {
     }
 
     /**
+     * Given one format and one course id, return the corresponding
+     * backup_xxx_format_task()
+     */
+    public static function get_backup_format_task($format, $courseid) {
+        global $DB;
+
+        // Check course exists
+        if (!$course = $DB->get_record('course', array('id' => $courseid))) {
+            throw new backup_task_exception('format_task_course_not_found', $courseid);
+        }
+
+        $classname = 'backup_format_' . $course->format . '_task';
+        return new $classname($course->format, $courseid);
+    }
+
+    /**
      * Dispatches the creation of the @backup_plan to the proper format builder
      */
     static public function build_plan($controller) {
diff --git a/backup/util/factories/restore_factory.class.php b/backup/util/factories/restore_factory.class.php
index 46ff794..652640a 100644
--- a/backup/util/factories/restore_factory.class.php
+++ b/backup/util/factories/restore_factory.class.php
@@ -66,4 +66,11 @@ abstract class restore_factory {
 
         return new restore_course_task($info->title, $info);
     }
+
+    public static function get_restore_format_task($info, $format) {
+        global $DB;
+
+        $classname = 'restore_format_' . $format . '_task';
+        return new $classname($format, $info);
+    }
 }
diff --git a/backup/util/helper/backup_general_helper.class.php b/backup/util/helper/backup_general_helper.class.php
index 99db287..eda5ecc 100644
--- a/backup/util/helper/backup_general_helper.class.php
+++ b/backup/util/helper/backup_general_helper.class.php
@@ -148,6 +148,7 @@ abstract class backup_general_helper extends backup_helper {
         $info->type   =  $infoarr['details']['detail'][0]['type'];
         $info->format =  $infoarr['details']['detail'][0]['format'];
         $info->mode   =  $infoarr['details']['detail'][0]['mode'];
+        $info->courseformat = $infoarr['details']['detail'][0]['courseformat'];
         // Build the role mappings custom object
         $rolemappings = new stdclass();
         $rolemappings->modified = false;
@@ -162,6 +163,11 @@ abstract class backup_general_helper extends backup_helper {
             $info->course = (object)$contentsarr['course'][0];
             $info->course->settings = array();
         }
+        if (isset($contentsarr['format']) && isset($contentsarr['format'][0])) {
+            $info->courseformat = new stdclass();
+            $info->courseformat = (object)$contentsarr['format'][0];
+            $info->courseformat->settings = array();
+        }
         if (isset($contentsarr['sections']) && isset($contentsarr['sections']['section'])) {
             $sectionarr = $contentsarr['sections']['section'];
             $sections = array();
@@ -194,6 +200,9 @@ abstract class backup_general_helper extends backup_helper {
                 case 'course':
                     $info->course->settings[$setting['name']] = $setting['value'];
                     break;
+                case 'format':
+                    $info->courseformat->settings[$setting['name']] = $setting['value'];
+                    break;
                 case 'section':
                     $info->sections[$setting['section']]->settings[$setting['name']] = $setting['value'];
                     break;
diff --git a/backup/util/helper/restore_moodlexml_parser_processor.class.php b/backup/util/helper/restore_moodlexml_parser_processor.class.php
index f95dfb0..2849775 100644
--- a/backup/util/helper/restore_moodlexml_parser_processor.class.php
+++ b/backup/util/helper/restore_moodlexml_parser_processor.class.php
@@ -44,6 +44,7 @@ class restore_moodlexml_parser_processor extends grouped_parser_processor {
         $this->add_path('/moodle_backup/information/contents/activities/activity');
         $this->add_path('/moodle_backup/information/contents/sections/section');
         $this->add_path('/moodle_backup/information/contents/course');
+        $this->add_path('/moodle_backup/information/contents/format');
         $this->add_path('/moodle_backup/information/settings/setting');
     }
 
diff --git a/backup/util/includes/restore_includes.php b/backup/util/includes/restore_includes.php
index ce9bf72..ec006fa 100644
--- a/backup/util/includes/restore_includes.php
+++ b/backup/util/includes/restore_includes.php
@@ -75,7 +75,6 @@ require_once($CFG->dirroot . '/backup/util/plan/base_step.class.php');
 require_once($CFG->dirroot . '/backup/util/plan/restore_step.class.php');
 require_once($CFG->dirroot . '/backup/util/plan/restore_structure_step.class.php');
 require_once($CFG->dirroot . '/backup/util/plan/restore_execution_step.class.php');
-require_once($CFG->dirroot . '/backup/moodle2/restore_plan_builder.class.php');
 require_once($CFG->dirroot . '/backup/controller/restore_controller.class.php');
 require_once($CFG->dirroot . '/backup/util/ui/base_moodleform.class.php');
 require_once($CFG->dirroot . '/backup/util/ui/base_ui.class.php');
diff --git a/course/lib.php b/course/lib.php
index 93ba342..032b9c2 100644
--- a/course/lib.php
+++ b/course/lib.php
@@ -3383,6 +3383,21 @@ function course_format_uses_sections($format) {
     return false;
 }
 
+function course_format_uses_backup($format) {
+    global $CFG;
+
+    $featurefile = $CFG->dirroot.'/course/format/'.$format.'/lib.php';
+    $featurefunction = 'callback_'.$format.'_uses_backup';
+    if (!function_exists($featurefunction) && file_exists($featurefile)) {
+        require_once $featurefile;
+    }
+    if (function_exists($featurefunction)) {
+        return $featurefunction();
+    }
+
+    return false;
+}
+
 /**
  * Can the current user delete this course?
  * Course creators have exception,
