first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
<?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/>.
/**
* 1.9 to 2.0 backup format converter. (Also currently used in common cartridge import process)
*
* @package mod_lti
* @copyright Copyright (c) 2011 Moodlerooms Inc. (http://www.moodlerooms.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Darko Miletic
*/
defined('MOODLE_INTERNAL') || die();
class moodle1_mod_lti_handler extends moodle1_mod_handler {
/** @var moodle1_file_manager */
protected $fileman = null;
/** @var int cmid */
protected $moduleid = null;
/**
* Declare the paths in moodle.xml we are able to convert
*
* The method returns list of {@link convert_path} instances.
* For each path returned, the corresponding conversion method must be
* defined.
*
* Note that the path /MOODLE_BACKUP/COURSE/MODULES/MOD/LTI does not
* actually exist in the file. The last element with the module name was
* appended by the moodle1_converter class.
*
* @return array of {@link convert_path} instances
*/
public function get_paths() {
return array(
new convert_path(
'basiclti', '/MOODLE_BACKUP/COURSE/MODULES/MOD/LTI'
)
);
}
/**
* This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/LTI
* data available
*/
public function process_basiclti($data) {
global $DB;
// Get the course module id and context id.
$instanceid = $data['id'];
$cminfo = $this->get_cminfo($instanceid);
$this->moduleid = $cminfo['id'];
$contextid = $this->converter->get_contextid(CONTEXT_MODULE, $this->moduleid);
// Get a fresh new file manager for this instance.
$this->fileman = $this->converter->get_file_manager($contextid, 'mod_lti');
// Convert course files embedded into the intro.
$this->fileman->filearea = 'intro';
$this->fileman->itemid = 0;
$data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman);
// Start writing assignment.xml.
$this->open_xml_writer("activities/lti_{$this->moduleid}/lti.xml");
$this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid,
'modulename' => 'lti', 'contextid' => $contextid));
$this->xmlwriter->begin_tag('lti', array('id' => $instanceid));
$ignorefields = array('id', 'modtype');
if (!$DB->record_exists('lti_types', array('id' => $data['typeid']))) {
$ntypeid = false;
$toolurls = $DB->get_records_select(
'lti_types_config',
"name = 'toolurl' AND " . $DB->sql_compare_text('value', 256) . ' = ' . $DB->sql_compare_text('?', 256),
[$data['toolurl']],
'',
'id, value'
);
foreach ($toolurls as $id => $value) {
if ($value == $data['toolurl']) {
$ntypeid = $id;
break;
}
}
if ($ntypeid === false) {
$ntypeid = $DB->get_field('lti_types_config',
'typeid',
array(),
IGNORE_MULTIPLE);
}
if ($ntypeid === false) {
$ntypeid = 0;
}
$data['typeid'] = $ntypeid;
}
if (empty($data['servicesalt'])) {
$data['servicesalt'] = uniqid('', true);
}
foreach ($data as $field => $value) {
if (!in_array($field, $ignorefields)) {
$this->xmlwriter->full_tag($field, $value);
}
}
return $data;
}
/**
* This is executed when we reach the closing </MOD> tag of our 'lti' path
*/
public function on_basiclti_end() {
// Finish writing basiclti.xml.
$this->xmlwriter->end_tag('lti');
$this->xmlwriter->end_tag('activity');
$this->close_xml_writer();
// Write inforef.xml.
$this->open_xml_writer("activities/lti_{$this->moduleid}/inforef.xml");
$this->xmlwriter->begin_tag('inforef');
$this->xmlwriter->begin_tag('fileref');
foreach ($this->fileman->get_fileids() as $fileid) {
$this->write_xml('file', array('id' => $fileid));
}
$this->xmlwriter->end_tag('fileref');
$this->xmlwriter->end_tag('inforef');
$this->close_xml_writer();
}
}
@@ -0,0 +1,91 @@
<?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/>.
//
// This file is part of BasicLTI4Moodle
//
// BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
// consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
// based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
// specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
// are already supporting or going to support BasicLTI. This project Implements the consumer
// for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
// BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
// at the GESSI research group at UPC.
// SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
// by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
// Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
//
// BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
// of the Universitat Politecnica de Catalunya http://www.upc.edu
// Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu.
/**
* Defines backup_lti_activity_task class
*
* @package mod_lti
* @category backup
* @copyright 2009 Marc Alier <marc.alier@upc.edu>, Jordi Piguillem, Nikolas Galanis
* @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
* @author Marc Alier
* @author Jordi Piguillem
* @author Nikolas Galanis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot . '/mod/lti/backup/moodle2/backup_lti_stepslib.php');
/**
* Provides the steps to perform one complete backup of the LTI instance
*/
class backup_lti_activity_task extends backup_activity_task {
/**
* No specific settings for this activity
*/
protected function define_my_settings() {
}
/**
* Defines a backup step to store the instance data in the lti.xml file
*/
protected function define_my_steps() {
$this->add_step(new backup_lti_activity_structure_step('lti_structure', 'lti.xml'));
}
/**
* Encodes URLs to the index.php and view.php scripts
*
* @param string $content some HTML text that eventually contains URLs to the activity instance scripts
* @return string the content with the URLs encoded
*/
public static function encode_content_links($content) {
global $CFG;
$base = preg_quote($CFG->wwwroot, "/");
// Link to the list of basiclti tools.
$search = "/(".$base."\/mod\/lti\/index.php\?id\=)([0-9]+)/";
$content = preg_replace($search, '$@LTIINDEX*$2@$', $content);
// Link to basiclti view by moduleid.
$search = "/(".$base."\/mod\/lti\/view.php\?id\=)([0-9]+)/";
$content = preg_replace($search, '$@LTIVIEWBYID*$2@$', $content);
return $content;
}
}
@@ -0,0 +1,265 @@
<?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/>.
//
// This file is part of BasicLTI4Moodle
//
// BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
// consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
// based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
// specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
// are already supporting or going to support BasicLTI. This project Implements the consumer
// for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
// BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
// at the GESSI research group at UPC.
// SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
// by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
// Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
//
// BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
// of the Universitat Politecnica de Catalunya http://www.upc.edu
// Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu.
/**
* This file contains all the backup steps that will be used
* by the backup_lti_activity_task
*
* @package mod_lti
* @copyright 2009 Marc Alier, Jordi Piguillem, Nikolas Galanis
* marc.alier@upc.edu
* @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
* @author Marc Alier
* @author Jordi Piguillem
* @author Nikolas Galanis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Define the complete assignment structure for backup, with file and id annotations
*/
class backup_lti_activity_structure_step extends backup_activity_structure_step {
/**
* Defines structure of activity backup
* @return backup_nested_element
*/
protected function define_structure() {
global $DB;
// To know if we are including userinfo.
$userinfo = $this->get_setting_value('userinfo');
// Define each element separated.
$lti = new backup_nested_element('lti', array('id'), array(
'name',
'intro',
'introformat',
'timecreated',
'timemodified',
'typeid',
'toolurl',
'securetoolurl',
'preferheight',
'launchcontainer',
'instructorchoicesendname',
'instructorchoicesendemailaddr',
'instructorchoiceacceptgrades',
'instructorchoiceallowroster',
'instructorchoiceallowsetting',
'grade',
'instructorcustomparameters',
'debuglaunch',
'showtitlelaunch',
'showdescriptionlaunch',
'icon',
'secureicon',
new encrypted_final_element('resourcekey'),
new encrypted_final_element('password'),
)
);
$ltitype = new backup_nested_element('ltitype', array('id'), array(
'name',
'baseurl',
'tooldomain',
'state',
'course',
'coursevisible',
'ltiversion',
'clientid',
'toolproxyid',
'enabledcapability',
'parameter',
'icon',
'secureicon',
'createdby',
'timecreated',
'timemodified',
'description'
)
);
$ltitypesconfigs = new backup_nested_element('ltitypesconfigs');
$ltitypesconfig = new backup_nested_element('ltitypesconfig', array('id'), array(
'name',
'value',
)
);
$ltitypesconfigencrypted = new backup_nested_element('ltitypesconfigencrypted', array('id'), array(
'name',
new encrypted_final_element('value'),
)
);
$ltitoolproxy = new backup_nested_element('ltitoolproxy', array('id'));
$ltitoolsettings = new backup_nested_element('ltitoolsettings');
$ltitoolsetting = new backup_nested_element('ltitoolsetting', array('id'), array(
'settings',
'timecreated',
'timemodified',
)
);
$ltisubmissions = new backup_nested_element('ltisubmissions');
$ltisubmission = new backup_nested_element('ltisubmission', array('id'), array(
'userid',
'datesubmitted',
'dateupdated',
'gradepercent',
'originalgrade',
'launchid',
'state'
));
$lticoursevisible = new backup_nested_element('lticoursevisible', ['id'], [
'typeid',
'courseid',
'coursevisible',
]);
// Build the tree
$lti->add_child($ltitype);
$ltitype->add_child($ltitypesconfigs);
$ltitypesconfigs->add_child($ltitypesconfig);
$ltitypesconfigs->add_child($ltitypesconfigencrypted);
$ltitype->add_child($ltitoolproxy);
$ltitoolproxy->add_child($ltitoolsettings);
$ltitoolsettings->add_child($ltitoolsetting);
$lti->add_child($ltisubmissions);
$ltisubmissions->add_child($ltisubmission);
$lti->add_child($lticoursevisible);
// Define sources.
$ltirecord = $DB->get_record('lti', ['id' => $this->task->get_activityid()]);
$lti->set_source_array([$ltirecord]);
$ltitypedata = $this->retrieve_lti_type($ltirecord);
$ltitype->set_source_array($ltitypedata ? [$ltitypedata] : []);
if (isset($ltitypedata->baseurl)) {
// Add type config values only if the type was backed up. Encrypt password and resourcekey.
$params = [backup_helper::is_sqlparam($ltitypedata->id),
backup_helper::is_sqlparam('password'),
backup_helper::is_sqlparam('resourcekey')];
$ltitypesconfig->set_source_sql("SELECT id, name, value
FROM {lti_types_config}
WHERE typeid = ? AND name <> ? AND name <> ?", $params);
$ltitypesconfigencrypted->set_source_sql("SELECT id, name, value
FROM {lti_types_config}
WHERE typeid = ? AND (name = ? OR name = ?)", $params);
}
if (!empty($ltitypedata->toolproxyid)) {
// If this is LTI 2 tool add settings for the current activity.
$ltitoolproxy->set_source_array([['id' => $ltitypedata->toolproxyid]]);
$ltitoolsetting->set_source_sql("SELECT *
FROM {lti_tool_settings}
WHERE toolproxyid = ? AND course = ? AND coursemoduleid = ?",
[backup_helper::is_sqlparam($ltitypedata->toolproxyid), backup::VAR_COURSEID, backup::VAR_MODID]);
} else {
$ltitoolproxy->set_source_array([]);
}
// All the rest of elements only happen if we are including user info.
if ($userinfo) {
$ltisubmission->set_source_table('lti_submission', array('ltiid' => backup::VAR_ACTIVITYID));
}
$lticoursevisibledata = $this->retrieve_lti_coursevisible($ltirecord);
$lticoursevisible->set_source_array($lticoursevisibledata ? [$lticoursevisibledata] : []);
// Define id annotations
$ltitype->annotate_ids('user', 'createdby');
$ltitype->annotate_ids('course', 'course');
$ltisubmission->annotate_ids('user', 'userid');
// Define file annotations.
$lti->annotate_files('mod_lti', 'intro', null); // This file areas haven't itemid.
// Add support for subplugin structures.
$this->add_subplugin_structure('ltisource', $lti, true);
$this->add_subplugin_structure('ltiservice', $lti, true);
// Return the root element (lti), wrapped into standard activity structure.
return $this->prepare_activity_structure($lti);
}
/**
* Retrieves a record from {lti_type} table associated with the current activity
*
* Information about site tools is not returned because it is insecure to back it up,
* only fields necessary for same-site tool matching are left in the record
*
* @param stdClass $ltirecord record from {lti} table
* @return stdClass|null
*/
protected function retrieve_lti_type($ltirecord) {
global $DB;
if (!$ltirecord->typeid) {
return null;
}
$record = $DB->get_record('lti_types', ['id' => $ltirecord->typeid]);
if ($record && $record->course == SITEID) {
// Site LTI types or registrations are not backed up except for their name (which is visible).
// Predefined course types can be backed up.
$allowedkeys = ['id', 'course', 'name', 'toolproxyid'];
foreach ($record as $key => $value) {
if (!in_array($key, $allowedkeys)) {
$record->$key = null;
}
}
}
return $record;
}
/**
* Retrieves a record from {lti_coursevisible} table associated with the current type
*
* @param stdClass $ltirecord record from {lti} table
* @return mixed
*/
protected function retrieve_lti_coursevisible(stdClass $ltirecord): mixed {
global $DB;
if (!$ltirecord->typeid) {
return null;
}
return $DB->get_record('lti_coursevisible', ['typeid' => $ltirecord->typeid, 'courseid' => $ltirecord->course]);
}
}
@@ -0,0 +1,132 @@
<?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/>.
//
// This file is part of BasicLTI4Moodle
//
// BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
// consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
// based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
// specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
// are already supporting or going to support BasicLTI. This project Implements the consumer
// for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
// BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
// at the GESSI research group at UPC.
// SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
// by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
// Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
//
// BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
// of the Universitat Politecnica de Catalunya http://www.upc.edu
// Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu.
/**
* This file contains the lti module restore class
*
* @package mod_lti
* @copyright 2009 Marc Alier, Jordi Piguillem, Nikolas Galanis
* marc.alier@upc.edu
* @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
* @author Marc Alier
* @author Jordi Piguillem
* @author Nikolas Galanis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/lti/backup/moodle2/restore_lti_stepslib.php');
/**
* basiclti restore task that provides all the settings and steps to perform one
* complete restore of the activity
*/
class restore_lti_activity_task extends restore_activity_task {
/**
* Define (add) particular settings this activity can have
*/
protected function define_my_settings() {
// No particular settings for this activity.
}
/**
* Define (add) particular steps this activity can have
*/
protected function define_my_steps() {
// Label only has one structure step.
$this->add_step(new restore_lti_activity_structure_step('lti_structure', 'lti.xml'));
}
/**
* Define the contents in the activity that must be
* processed by the link decoder
*/
public static function define_decode_contents() {
$contents = array();
$contents[] = new restore_decode_content('lti', array('intro'), 'lti');
return $contents;
}
/**
* Define the decoding rules for links belonging
* to the activity to be executed by the link decoder
*/
public static function define_decode_rules() {
$rules = array();
$rules[] = new restore_decode_rule('LTIVIEWBYID', '/mod/lti/view.php?id=$1', 'course_module');
$rules[] = new restore_decode_rule('LTIINDEX', '/mod/lti/index.php?id=$1', 'course');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* basiclti logs. It must return one array
* of {@link restore_log_rule} objects
*/
public static function define_restore_log_rules() {
$rules = array();
$rules[] = new restore_log_rule('lti', 'add', 'view.php?id={course_module}', '{lti}');
$rules[] = new restore_log_rule('lti', 'update', 'view.php?id={course_module}', '{lti}');
$rules[] = new restore_log_rule('lti', 'view', 'view.php?id={course_module}', '{lti}');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* course logs. It must return one array
* of {@link restore_log_rule} objects
*
* Note this rules are applied when restoring course logs
* by the restore final task, but are defined here at
* activity level. All them are rules not linked to any module instance (cmid = 0)
*/
public static function define_restore_log_rules_for_course() {
$rules = array();
$rules[] = new restore_log_rule('lti', 'view all', 'index.php?id={course}', null);
return $rules;
}
}
@@ -0,0 +1,310 @@
<?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/>.
//
// This file is part of BasicLTI4Moodle
//
// BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
// consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
// based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
// specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
// are already supporting or going to support BasicLTI. This project Implements the consumer
// for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
// BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
// at the GESSI research group at UPC.
// SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
// by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
// Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
//
// BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
// of the Universitat Politecnica de Catalunya http://www.upc.edu
// Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu.
/**
* This file contains all the restore steps that will be used
* by the restore_lti_activity_task
*
* @package mod_lti
* @copyright 2009 Marc Alier, Jordi Piguillem, Nikolas Galanis
* marc.alier@upc.edu
* @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
* @author Marc Alier
* @author Jordi Piguillem
* @author Nikolas Galanis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
use mod_lti\local\ltiopenid\registration_helper;
/**
* Structure step to restore one lti activity
*/
class restore_lti_activity_structure_step extends restore_activity_structure_step {
/** @var bool */
protected $newltitype = false;
protected function define_structure() {
$paths = array();
// To know if we are including userinfo.
$userinfo = $this->get_setting_value('userinfo');
$lti = new restore_path_element('lti', '/activity/lti');
$paths[] = $lti;
$paths[] = new restore_path_element('ltitype', '/activity/lti/ltitype');
$paths[] = new restore_path_element('ltitypesconfig', '/activity/lti/ltitype/ltitypesconfigs/ltitypesconfig');
$paths[] = new restore_path_element('ltitypesconfigencrypted',
'/activity/lti/ltitype/ltitypesconfigs/ltitypesconfigencrypted');
$paths[] = new restore_path_element('ltitoolproxy', '/activity/lti/ltitype/ltitoolproxy');
$paths[] = new restore_path_element('ltitoolsetting', '/activity/lti/ltitype/ltitoolproxy/ltitoolsettings/ltitoolsetting');
if ($userinfo) {
$submission = new restore_path_element('ltisubmission', '/activity/lti/ltisubmissions/ltisubmission');
$paths[] = $submission;
}
$paths[] = new restore_path_element('lticoursevisible', '/activity/lti/lticoursevisible');
// Add support for subplugin structures.
$this->add_subplugin_structure('ltisource', $lti);
$this->add_subplugin_structure('ltiservice', $lti);
// Return the paths wrapped into standard activity structure.
return $this->prepare_activity_structure($paths);
}
protected function process_lti($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->course = $this->get_courseid();
$data->servicesalt = uniqid('', true);
// Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
// See MDL-9367.
// Grade used to be a float (whole numbers only), restore as int.
$data->grade = (int) $data->grade;
$data->typeid = 0;
// Try to decrypt resourcekey and password. Null if not possible (DB default).
// Note these fields were originally encrypted on backup using {link @encrypted_final_element}.
$data->resourcekey = isset($data->resourcekey) ? $this->decrypt($data->resourcekey) : null;
$data->password = isset($data->password) ? $this->decrypt($data->password) : null;
$newitemid = $DB->insert_record('lti', $data);
// Immediately after inserting "activity" record, call this.
$this->apply_activity_instance($newitemid);
}
/**
* Process an lti type restore
* @param mixed $data The data from backup XML file
* @return void
*/
protected function process_ltitype($data) {
global $DB, $USER;
$data = (object)$data;
$oldid = $data->id;
if (!empty($data->createdby)) {
$data->createdby = $this->get_mappingid('user', $data->createdby) ?: $USER->id;
}
$courseid = $this->get_courseid();
$data->course = ($this->get_mappingid('course', $data->course) == $courseid) ? $courseid : SITEID;
// Try to find existing lti type with the same properties.
$ltitypeid = $this->find_existing_lti_type($data);
$this->newltitype = false;
if (!$ltitypeid && $data->course == $courseid) {
unset($data->toolproxyid); // Course tools can not use LTI2.
if (!empty($data->clientid)) {
// Need to rebuild clientid to ensure uniqueness.
$data->clientid = registration_helper::get()->new_clientid();
}
$ltitypeid = $DB->insert_record('lti_types', $data);
$this->newltitype = true;
$this->set_mapping('ltitype', $oldid, $ltitypeid);
}
// Add the typeid entry back to LTI module.
$DB->update_record('lti', ['id' => $this->get_new_parentid('lti'), 'typeid' => $ltitypeid]);
}
/**
* Process an lti coursevisible restore
* @param mixed $data The data from backup XML file
* @return void
*/
protected function process_lticoursevisible($data) {
global $DB;
$data = (object)$data;
$data->typeid = $this->get_new_parentid('ltitype');
$data->courseid = $this->get_courseid();
if ($data->typeid) {
$DB->insert_record('lti_coursevisible', $data);
}
}
/**
* Attempts to find existing record in lti_type
* @param stdClass $data
* @return int|null field lti_types.id or null if tool is not found
*/
protected function find_existing_lti_type($data) {
global $DB;
if ($ltitypeid = $this->get_mappingid('ltitype', $data->id)) {
return $ltitypeid;
}
$ltitype = null;
$params = (array)$data;
if ($this->task->is_samesite()) {
// If we are restoring on the same site try to find lti type with the same id.
$sql = 'id = :id AND course = :course';
$sql .= ($data->toolproxyid) ? ' AND toolproxyid = :toolproxyid' : ' AND toolproxyid IS NULL';
if ($DB->record_exists_select('lti_types', $sql, $params)) {
$this->set_mapping('ltitype', $data->id, $data->id);
if ($data->toolproxyid) {
$this->set_mapping('ltitoolproxy', $data->toolproxyid, $data->toolproxyid);
}
return $data->id;
}
}
if ($data->course != $this->get_courseid()) {
// Site tools are not backed up and are not restored.
return null;
}
// Now try to find the same type on the current site available in this course.
// Compare only fields baseurl, course and name, if they are the same we assume it is the same tool.
// LTI2 is not possible in the course so we add "lt.toolproxyid IS NULL" to the query.
$sql = 'SELECT id
FROM {lti_types}
WHERE ' . $DB->sql_compare_text('baseurl', 255) . ' = ' . $DB->sql_compare_text(':baseurl', 255) . ' AND
course = :course AND name = :name AND toolproxyid IS NULL';
if ($ltitype = $DB->get_record_sql($sql, $params, IGNORE_MULTIPLE)) {
$this->set_mapping('ltitype', $data->id, $ltitype->id);
return $ltitype->id;
}
return null;
}
/**
* Process an lti config restore
* @param mixed $data The data from backup XML file
*/
protected function process_ltitypesconfig($data) {
global $DB;
$data = (object)$data;
$data->typeid = $this->get_new_parentid('ltitype');
// Only add configuration if the new lti_type was created.
if ($data->typeid && $this->newltitype) {
if ($data->name == 'servicesalt') {
$data->value = uniqid('', true);
}
$DB->insert_record('lti_types_config', $data);
}
}
/**
* Process an lti config restore
* @param mixed $data The data from backup XML file
*/
protected function process_ltitypesconfigencrypted($data) {
global $DB;
$data = (object)$data;
$data->typeid = $this->get_new_parentid('ltitype');
// Only add configuration if the new lti_type was created.
if ($data->typeid && $this->newltitype) {
$data->value = $this->decrypt($data->value);
if (!is_null($data->value)) {
$DB->insert_record('lti_types_config', $data);
}
}
}
/**
* Process a restore of LTI tool registration
* This method is empty because we actually process registration as part of process_ltitype()
* @param mixed $data The data from backup XML file
*/
protected function process_ltitoolproxy($data) {
}
/**
* Process an lti tool registration settings restore (only settings for the current activity)
* @param mixed $data The data from backup XML file
*/
protected function process_ltitoolsetting($data) {
global $DB;
$data = (object)$data;
$data->toolproxyid = $this->get_new_parentid('ltitoolproxy');
if (!$data->toolproxyid) {
return;
}
$data->course = $this->get_courseid();
$data->coursemoduleid = $this->task->get_moduleid();
$DB->insert_record('lti_tool_settings', $data);
}
/**
* Process a submission restore
* @param mixed $data The data from backup XML file
*/
protected function process_ltisubmission($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->ltiid = $this->get_new_parentid('lti');
$data->datesubmitted = $this->apply_date_offset($data->datesubmitted);
$data->dateupdated = $this->apply_date_offset($data->dateupdated);
if ($data->userid > 0) {
$data->userid = $this->get_mappingid('user', $data->userid);
}
$newitemid = $DB->insert_record('lti_submission', $data);
$this->set_mapping('ltisubmission', $oldid, $newitemid);
}
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);
}
}