diff --git a/mod/lti/backup/moodle2/backup_lti_stepslib.php b/mod/lti/backup/moodle2/backup_lti_stepslib.php index e6ad077ef22..0dbc7782f70 100644 --- a/mod/lti/backup/moodle2/backup_lti_stepslib.php +++ b/mod/lti/backup/moodle2/backup_lti_stepslib.php @@ -55,8 +55,6 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step protected function define_structure() { - // TODO: MDL-34161 - Fix restore to support course/site tools & submissions. - // To know if we are including userinfo. $userinfo = $this->get_setting_value('userinfo'); @@ -89,14 +87,50 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step ) ); + $ltitypes = new backup_nested_element('ltitypes'); + $ltitype = new backup_nested_element('ltitype', array('id'), array( + 'name', + 'baseurl', + 'tooldomain', + 'state', + 'coursevisible', + 'createdby', + 'timecreated', + 'timemodified', + ) + ); + + $ltitypesconfigs = new backup_nested_element('ltitypesconfigs'); + $ltitypesconfig = new backup_nested_element('ltitypesconfig', array('id'), array( + 'typeid', + 'name', + 'value', + ) + ); + // Build the tree - // (none). + $lti->add_child($ltitypes); + $lti->add_child($ltitypesconfigs); + $ltitypes->add_child($ltitype); + $ltitypesconfigs->add_child($ltitypesconfig); // Define sources. $lti->set_source_table('lti', array('id' => backup::VAR_ACTIVITYID)); + $ltitype->set_source_sql("SELECT lt.* + FROM {lti} l + JOIN {lti_types} lt ON lt.id = l.typeid + WHERE l.id = ?", array(backup::VAR_ACTIVITYID)); + $ltitypesconfig->set_source_sql("SELECT lc.* + FROM {lti} l + JOIN {lti_types_config} lc ON lc.typeid = l.typeid + WHERE lc.name != 'password' + AND lc.name != 'resourcekey' + AND lc.name != 'servicesalt' + AND l.id = ?", array(backup::VAR_ACTIVITYID)); + // Define id annotations - // (none). + $ltitype->annotate_ids('user', 'createdby'); // Define file annotations. $lti->annotate_files('mod_lti', 'intro', null); // This file areas haven't itemid. diff --git a/mod/lti/backup/moodle2/restore_lti_stepslib.php b/mod/lti/backup/moodle2/restore_lti_stepslib.php index f57186a2044..cfed5c9c4bd 100644 --- a/mod/lti/backup/moodle2/restore_lti_stepslib.php +++ b/mod/lti/backup/moodle2/restore_lti_stepslib.php @@ -57,6 +57,8 @@ class restore_lti_activity_structure_step extends restore_activity_structure_ste $paths = array(); $lti = new restore_path_element('lti', '/activity/lti'); + $paths[] = new restore_path_element('ltitype', '/activity/lti/ltitypes/ltitype'); + $paths[] = new restore_path_element('ltitypesconfig', '/activity/lti/ltitypesconfigs/ltitypesconfig'); $paths[] = $lti; // Add support for subplugin structures. @@ -81,10 +83,6 @@ class restore_lti_activity_structure_step extends restore_activity_structure_ste // Grade used to be a float (whole numbers only), restore as int. $data->grade = (int) $data->grade; - // Clean any course or site typeid. All modules - // are restored as self-contained. Note this is - // an interim solution until the issue below is implemented. - // TODO: MDL-34161 - Fix restore to support course/site tools & submissions. $data->typeid = 0; // Try to decrypt resourcekey and password. Null if not possible (DB default). @@ -98,6 +96,72 @@ class restore_lti_activity_structure_step extends restore_activity_structure_ste $this->apply_activity_instance($newitemid); } + /** + * Process an lti type restore + * @param object $data The data in object form + * @return void + */ + protected function process_ltitype($data) { + global $DB; + + $data = (object)$data; + $data->createdby = $this->get_mappingid('user', $data->createdby); + $ltitype = $DB->get_record_sql("SELECT * + FROM {lti_types} + WHERE id = ? + AND baseurl = ?", array($data->id, $data->baseurl)); + + // If restore is occurring on the same site, don't add lti_types data if + // restoring on the SITEID. If restore isn't occurring on the same site, + // always add lti_type data from backup. + if ($this->task->is_samesite() && $ltitype->course != SITEID + && $ltitype->state == LTI_TOOL_STATE_CONFIGURED) { + // If restoring into the same course, use existing data, else re-create. + $course = $this->get_courseid(); + if ($ltitype->course != $course) { + $data->course = $course; + $ltitype = new stdClass(); + $ltitype->id = $DB->insert_record('lti_types', $data); + } + } else if (!$this->task->is_samesite() || !isset($ltitype->id)) { + // Either we are restoring into a new site, or didn't find a database match. + $data->course = $this->get_courseid(); + $ltitype = new stdClass(); + $ltitype->id = $DB->insert_record('lti_types', $data); + } + + // Add the typeid entry back to LTI module. + $lti = new stdClass(); + $lti->id = $this->get_new_parentid('lti'); + $lti->typeid = $ltitype->id; + $DB->update_record('lti', $lti); + } + + /** + * Process an lti config restore + * @param object $data The data in object form + * @return void + */ + protected function process_ltitypesconfig($data) { + global $DB; + + $data = (object)$data; + + $parentid = $this->get_new_parentid('lti'); + $lti = $DB->get_record_sql("SELECT typeid + FROM {lti} + WHERE id = ?", array($parentid)); + + // Only add configuration if typeid doesn't match new LTI tool. + if ($lti->typeid != $data->typeid) { + $data->typeid = $lti->typeid; + if ($data->name == 'servicesalt') { + $data->value = uniqid('', true); + } + $DB->insert_record('lti_types_config', $data); + } + } + protected function after_execute() { // Add lti related files, no need to match by itemname (just internally handled context). $this->add_related_files('mod_lti', 'intro', null);