mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-49609 mod_lti: Add Content-Item message
Added option for tools to support Content-Item message and redirect to/from tool provider when creating an instance.
This commit is contained in:
parent
1f2744851f
commit
d8f9109a12
89
mod/lti/contentitem.php
Normal file
89
mod/lti/contentitem.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Display a page containing an iframe for the content-item selection process.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Vital Source Technologies http://vitalsource.com
|
||||
* @author Stephen Vickers
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../../config.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
|
||||
$courseid = required_param('course', PARAM_INT);
|
||||
$sectionid = required_param('section', PARAM_INT);
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$sectionreturn = required_param('sr', PARAM_INT);
|
||||
|
||||
$title = optional_param('title', null, PARAM_TEXT);
|
||||
|
||||
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
|
||||
|
||||
require_login($course);
|
||||
|
||||
$url = new moodle_url('/mod/lti/contentitem.php', array('course' => $courseid));
|
||||
|
||||
$contentitem = new moodle_url('/mod/lti/contentitem2.php',
|
||||
array('course' => $courseid, 'section' => $sectionid, 'id' => $id, 'sr' => $sectionreturn, 'title' => $title));
|
||||
|
||||
echo "<p id=\"id_warning\" style=\"display: none; color: red; font-weight: bold; margin-top: 1em; padding-top: 1em;\">\n";
|
||||
echo get_string('register_warning', 'lti');
|
||||
echo "\n</p>\n";
|
||||
|
||||
echo '<iframe id="contentframe" height="600px" width="100%" src="' . $contentitem->out() . '" onload="doOnload()"></iframe>';
|
||||
|
||||
// Output script to make the object tag be as large as possible.
|
||||
$resize = '
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function doReveal() {
|
||||
var el = document.getElementById(\'id_warning\');
|
||||
el.style.display = \'block\';
|
||||
}
|
||||
function doOnload() {
|
||||
window.clearTimeout(mod_lti_timer);
|
||||
parent.M.mod_lti.editor.removeLoading();
|
||||
}
|
||||
var mod_lti_timer = window.setTimeout(doReveal, 20000);
|
||||
parent.YUI().use("node", "event", function(Y) {
|
||||
//Take scrollbars off the outer document to prevent double scroll bar effect
|
||||
var doc = parent.Y.one("body");
|
||||
doc.setStyle("overflow", "hidden");
|
||||
|
||||
var frame = parent.Y.one("#contentframe");
|
||||
var padding = 15; //The bottom of the iframe wasn\'t visible on some themes. Probably because of border widths, etc.
|
||||
var lastHeight;
|
||||
var resize = function(e) {
|
||||
var viewportHeight = doc.get("winHeight");
|
||||
if(lastHeight !== Math.min(doc.get("docHeight"), viewportHeight)){
|
||||
frame.setStyle("height", viewportHeight - frame.getY() - padding + "px");
|
||||
lastHeight = Math.min(doc.get("docHeight"), doc.get("winHeight"));
|
||||
}
|
||||
};
|
||||
|
||||
resize();
|
||||
|
||||
parent.Y.on("windowresize", resize);
|
||||
});
|
||||
//]]
|
||||
</script>
|
||||
';
|
||||
|
||||
echo $resize;
|
196
mod/lti/contentitem2.php
Normal file
196
mod/lti/contentitem2.php
Normal file
@ -0,0 +1,196 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Handle sending a user to a tool provider to initiate a content-item selection.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Vital Source Technologies http://vitalsource.com
|
||||
* @author Stephen Vickers
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once("../../config.php");
|
||||
require_once($CFG->dirroot.'/mod/lti/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
|
||||
$courseid = required_param('course', PARAM_INT);
|
||||
$sectionid = required_param('section', PARAM_INT);
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$sectionreturn = required_param('sr', PARAM_INT);
|
||||
|
||||
require_login($PAGE->course);
|
||||
|
||||
$tool = lti_get_type($id);
|
||||
$typeconfig = lti_get_type_config($id);
|
||||
if (isset($tool->toolproxyid)) {
|
||||
$toolproxy = lti_get_tool_proxy($tool->toolproxyid);
|
||||
$key = $toolproxy->guid;
|
||||
$secret = $toolproxy->secret;
|
||||
} else {
|
||||
$toolproxy = null;
|
||||
if (!empty($instance->resourcekey)) {
|
||||
$key = $instance->resourcekey;
|
||||
} else if (!empty($typeconfig['resourcekey'])) {
|
||||
$key = $typeconfig['resourcekey'];
|
||||
} else {
|
||||
$key = '';
|
||||
}
|
||||
if (!empty($instance->password)) {
|
||||
$secret = $instance->password;
|
||||
} else if (!empty($typeconfig['password'])) {
|
||||
$secret = $typeconfig['password'];
|
||||
} else {
|
||||
$secret = '';
|
||||
}
|
||||
}
|
||||
$tool->enabledcapability = $typeconfig['enabledcapability_ContentItemSelectionRequest'];
|
||||
$tool->parameter = $typeconfig['parameter_ContentItemSelectionRequest'];
|
||||
|
||||
$title = optional_param('title', $tool->name, PARAM_TEXT);
|
||||
|
||||
if (isset($typeconfig['toolurl_ContentItemSelectionRequest'])) {
|
||||
$endpoint = $typeconfig['toolurl_ContentItemSelectionRequest'];
|
||||
} else {
|
||||
$endpoint = !empty($instance->toolurl) ? $instance->toolurl : $typeconfig['toolurl'];
|
||||
}
|
||||
$endpoint = trim($endpoint);
|
||||
|
||||
// If the current request is using SSL and a secure tool URL is specified, use it.
|
||||
if (lti_request_is_using_ssl() && !empty($instance->securetoolurl)) {
|
||||
$endpoint = trim($instance->securetoolurl);
|
||||
}
|
||||
|
||||
// If SSL is forced, use the secure tool url if specified. Otherwise, make sure https is on the normal launch URL.
|
||||
if (isset($typeconfig['forcessl']) && ($typeconfig['forcessl'] == '1')) {
|
||||
if (!empty($instance->securetoolurl)) {
|
||||
$endpoint = trim($instance->securetoolurl);
|
||||
}
|
||||
|
||||
$endpoint = lti_ensure_url_is_https($endpoint);
|
||||
} else {
|
||||
if (!strstr($endpoint, '://')) {
|
||||
$endpoint = 'http://' . $endpoint;
|
||||
}
|
||||
}
|
||||
|
||||
$orgid = (isset($typeconfig['organizationid'])) ? $typeconfig['organizationid'] : '';
|
||||
|
||||
$course = $PAGE->course;
|
||||
$islti2 = isset($tool->toolproxyid);
|
||||
$instance = new stdClass();
|
||||
$instance->course = $courseid;
|
||||
$allparams = lti_build_request($instance, $typeconfig, $course, $id, $islti2);
|
||||
if ($islti2) {
|
||||
$requestparams = lti_build_request_lti2($tool, $allparams);
|
||||
} else {
|
||||
$requestparams = $allparams;
|
||||
}
|
||||
$requestparams = array_merge($requestparams, lti_build_standard_request(null, $orgid, $islti2));
|
||||
$customstr = '';
|
||||
if (isset($typeconfig['customparameters'])) {
|
||||
$customstr = $typeconfig['customparameters'];
|
||||
}
|
||||
$requestparams = array_merge($requestparams, lti_build_custom_parameters($toolproxy, $tool, $instance, $allparams, $customstr,
|
||||
'', $islti2));
|
||||
|
||||
// Allow request params to be updated by sub-plugins.
|
||||
$plugins = core_component::get_plugin_list('ltisource');
|
||||
foreach (array_keys($plugins) as $plugin) {
|
||||
$pluginparams = component_callback('ltisource_'.$plugin, 'before_launch',
|
||||
array($instance, $endpoint, $requestparams), array());
|
||||
|
||||
if (!empty($pluginparams) && is_array($pluginparams)) {
|
||||
$requestparams = array_merge($requestparams, $pluginparams);
|
||||
}
|
||||
}
|
||||
|
||||
if ($islti2) {
|
||||
$requestparams['lti_version'] = 'LTI-2p0';
|
||||
} else {
|
||||
$requestparams['lti_version'] = 'LTI-1p0';
|
||||
}
|
||||
$requestparams['lti_message_type'] = 'ContentItemSelectionRequest';
|
||||
|
||||
$requestparams['accept_media_types'] = 'application/vnd.ims.lti.v1.ltilink';
|
||||
$requestparams['accept_presentation_document_targets'] = 'frame,iframe,window';
|
||||
$requestparams['accept_unsigned'] = 'false';
|
||||
$requestparams['accept_multiple'] = 'false';
|
||||
$requestparams['auto_create'] = 'true';
|
||||
$requestparams['can_confirm'] = 'false';
|
||||
$requestparams['accept_copy_advice'] = 'false';
|
||||
$requestparams['title'] = $title;
|
||||
|
||||
$returnurlparams = array('course' => $courseid,
|
||||
'section' => $sectionid,
|
||||
'id' => $id,
|
||||
'sr' => $sectionreturn,
|
||||
'sesskey' => sesskey());
|
||||
|
||||
// Add the return URL. We send the launch container along to help us avoid frames-within-frames when the user returns.
|
||||
$url = new \moodle_url('/mod/lti/contentitem_return.php', $returnurlparams);
|
||||
$returnurl = $url->out(false);
|
||||
|
||||
if (isset($typeconfig['forcessl']) && ($typeconfig['forcessl'] == '1')) {
|
||||
$returnurl = lti_ensure_url_is_https($returnurl);
|
||||
}
|
||||
|
||||
$requestparams['content_item_return_url'] = $returnurl;
|
||||
|
||||
|
||||
$parms = lti_sign_parameters($requestparams, $endpoint, "POST", $key, $secret);
|
||||
|
||||
$endpointurl = new \moodle_url($endpoint);
|
||||
$endpointparams = $endpointurl->params();
|
||||
|
||||
// Strip querystring params in endpoint url from $parms to avoid duplication.
|
||||
if (!empty($endpointparams) && !empty($parms)) {
|
||||
foreach (array_keys($endpointparams) as $paramname) {
|
||||
if (isset($parms[$paramname])) {
|
||||
unset($parms[$paramname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "<p id=\"id_warning\" style=\"display: none; color: red; font-weight: bold; margin-top: 1em; padding-top: 1em;\">\n";
|
||||
echo get_string('register_warning', 'lti');
|
||||
echo "\n</p>\n";
|
||||
|
||||
$loading = $OUTPUT->render(new \pix_icon('i/loading', '', 'moodle',
|
||||
array('style' => 'margin:auto;vertical-align:middle;margin-top:125px;',
|
||||
'opacity' => '0.5')));
|
||||
|
||||
echo "<p style=\"text-align:center;\">\n";
|
||||
echo $loading;
|
||||
echo "\n</p>\n";
|
||||
|
||||
$script = '
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function doReveal() {
|
||||
var el = document.getElementById(\'id_warning\');
|
||||
el.style.display = \'block\';
|
||||
}
|
||||
var mod_lti_timer = window.setTimeout(doReveal, 20000);
|
||||
//]]
|
||||
</script>
|
||||
';
|
||||
|
||||
echo $script;
|
||||
|
||||
$content = lti_post_launch_html($parms, $endpoint, false);
|
||||
|
||||
echo $content;
|
226
mod/lti/contentitem_return.php
Normal file
226
mod/lti/contentitem_return.php
Normal file
@ -0,0 +1,226 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Handle the return from the Tool Provider after selecting a content item.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Vital Source Technologies http://vitalsource.com
|
||||
* @author Stephen Vickers
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../../config.php');
|
||||
require_once($CFG->dirroot . '/course/modlib.php');
|
||||
require_once($CFG->dirroot . '/mod/lti/lib.php');
|
||||
require_once($CFG->dirroot . '/mod/lti/locallib.php');
|
||||
require_once($CFG->dirroot . '/mod/lti/OAuth.php');
|
||||
require_once($CFG->dirroot . '/mod/lti/TrivialStore.php');
|
||||
|
||||
use moodle\mod\lti as lti;
|
||||
|
||||
$courseid = required_param('course', PARAM_INT);
|
||||
$sectionid = required_param('section', PARAM_INT);
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$sectionreturn = required_param('sr', PARAM_INT);
|
||||
$messagetype = required_param('lti_message_type', PARAM_TEXT);
|
||||
$version = required_param('lti_version', PARAM_TEXT);
|
||||
$consumer_key = required_param('oauth_consumer_key', PARAM_RAW);
|
||||
|
||||
$items = optional_param('content_items', '', PARAM_RAW);
|
||||
$errormsg = optional_param('lti_errormsg', '', PARAM_TEXT);
|
||||
$msg = optional_param('lti_msg', '', PARAM_TEXT);
|
||||
|
||||
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
|
||||
$module = $DB->get_record('modules', array('name' => 'lti'), '*', MUST_EXIST);
|
||||
$tool = lti_get_type($id);
|
||||
$typeconfig = lti_get_type_config($id);
|
||||
|
||||
require_login($course);
|
||||
require_sesskey();
|
||||
|
||||
if (isset($tool->toolproxyid)) {
|
||||
$toolproxy = lti_get_tool_proxy($tool->toolproxyid);
|
||||
$key = $toolproxy->guid;
|
||||
$secret = $toolproxy->secret;
|
||||
} else {
|
||||
$toolproxy = null;
|
||||
if (!empty($instance->resourcekey)) {
|
||||
$key = $instance->resourcekey;
|
||||
} else if (!empty($typeconfig['resourcekey'])) {
|
||||
$key = $typeconfig['resourcekey'];
|
||||
} else {
|
||||
$key = '';
|
||||
}
|
||||
if (!empty($instance->password)) {
|
||||
$secret = $instance->password;
|
||||
} else if (!empty($typeconfig['password'])) {
|
||||
$secret = $typeconfig['password'];
|
||||
} else {
|
||||
$secret = '';
|
||||
}
|
||||
}
|
||||
|
||||
if ($consumer_key !== $key) {
|
||||
throw new Exception('Consumer key is incorrect.');
|
||||
}
|
||||
|
||||
$store = new lti\TrivialOAuthDataStore();
|
||||
$store->add_consumer($key, $secret);
|
||||
|
||||
$server = new lti\OAuthServer($store);
|
||||
|
||||
$method = new lti\OAuthSignatureMethod_HMAC_SHA1();
|
||||
$server->add_signature_method($method);
|
||||
$request = lti\OAuthRequest::from_request();
|
||||
|
||||
try {
|
||||
$server->verify_request($request);
|
||||
} catch (\Exception $e) {
|
||||
$message = $e->getMessage();
|
||||
debugging($e->getMessage() . "\n");
|
||||
throw new lti\OAuthException("OAuth signature failed: " . $message);
|
||||
}
|
||||
|
||||
if ($items) {
|
||||
$items = json_decode($items);
|
||||
if ($items->{'@context'} !== 'http://purl.imsglobal.org/ctx/lti/v1/ContentItem') {
|
||||
throw new Exception('Invalid media type.');
|
||||
}
|
||||
if (!isset($items->{'@graph'}) || !is_array($items->{'@graph'}) || (count($items->{'@graph'}) > 1)) {
|
||||
throw new Exception('Invalid format.');
|
||||
}
|
||||
}
|
||||
|
||||
$continueurl = course_get_url($course, $sectionid, array('sr' => $sectionreturn));
|
||||
if (count($items->{'@graph'}) > 0) {
|
||||
foreach ($items->{'@graph'} as $item) {
|
||||
$moduleinfo = new stdClass();
|
||||
$moduleinfo->modulename = 'lti';
|
||||
$moduleinfo->name = '';
|
||||
if (isset($item->title)) {
|
||||
$moduleinfo->name = $item->title;
|
||||
}
|
||||
if (empty($moduleinfo->name)) {
|
||||
$moduleinfo->name = $tool->name;
|
||||
}
|
||||
$moduleinfo->module = $module->id;
|
||||
$moduleinfo->section = $sectionid;
|
||||
$moduleinfo->visible = 1;
|
||||
if (isset($item->url)) {
|
||||
$moduleinfo->toolurl = $item->url;
|
||||
$moduleinfo->typeid = 0;
|
||||
} else {
|
||||
$moduleinfo->typeid = $id;
|
||||
}
|
||||
$moduleinfo->instructorchoicesendname = LTI_SETTING_NEVER;
|
||||
$moduleinfo->instructorchoicesendemailaddr = LTI_SETTING_NEVER;
|
||||
$moduleinfo->instructorchoiceacceptgrades = LTI_SETTING_NEVER;
|
||||
$moduleinfo->launchcontainer = LTI_LAUNCH_CONTAINER_DEFAULT;
|
||||
if (isset($item->placementAdvice->presentationDocumentTarget)) {
|
||||
if ($item->placementAdvice->presentationDocumentTarget === 'window') {
|
||||
$moduleinfo->launchcontainer = LTI_LAUNCH_CONTAINER_WINDOW;
|
||||
} else if ($item->placementAdvice->presentationDocumentTarget === 'frame') {
|
||||
$moduleinfo->launchcontainer = LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS;
|
||||
} else if ($item->placementAdvice->presentationDocumentTarget === 'iframe') {
|
||||
$moduleinfo->launchcontainer = LTI_LAUNCH_CONTAINER_EMBED;
|
||||
}
|
||||
}
|
||||
if (isset($item->custom)) {
|
||||
$moduleinfo->instructorcustomparameters = '';
|
||||
$first = true;
|
||||
foreach ($item->custom as $key => $value) {
|
||||
if (!$first) {
|
||||
$moduleinfo->instructorcustomparameters .= "\n";
|
||||
}
|
||||
$moduleinfo->instructorcustomparameters .= "{$key}={$value}";
|
||||
$first = false;
|
||||
}
|
||||
}
|
||||
$moduleinfo = add_moduleinfo($moduleinfo, $course, null);
|
||||
}
|
||||
$clickhere = get_string('click_to_continue', 'lti', (object)array('link' => $continueurl->out()));
|
||||
} else {
|
||||
$clickhere = get_string('return_to_course', 'lti', (object)array('link' => $continueurl->out()));
|
||||
}
|
||||
|
||||
if (!empty($errormsg) || !empty($msg)) {
|
||||
|
||||
$url = new moodle_url('/mod/lti/contentitem_return.php',
|
||||
array('course' => $courseid));
|
||||
$PAGE->set_url($url);
|
||||
|
||||
$pagetitle = strip_tags($course->shortname);
|
||||
$PAGE->set_title($pagetitle);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
|
||||
$PAGE->set_pagelayout('embedded');
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
if (!empty($lti) and !empty($context)) {
|
||||
echo $OUTPUT->heading(format_string($lti->name, true, array('context' => $context)));
|
||||
}
|
||||
|
||||
if (!empty($errormsg)) {
|
||||
|
||||
echo '<p style="color: #f00; font-weight: bold; margin: 1em;">';
|
||||
echo get_string('lti_launch_error', 'lti') . ' ';
|
||||
p($errormsg);
|
||||
echo "</p>\n";
|
||||
|
||||
}
|
||||
|
||||
if (!empty($msg)) {
|
||||
|
||||
echo '<p style="margin: 1em;">';
|
||||
p($msg);
|
||||
echo "</p>\n";
|
||||
|
||||
}
|
||||
|
||||
echo "<p style=\"margin: 1em;\">{$clickhere}</p>";
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
} else {
|
||||
|
||||
$url = $continueurl->out();
|
||||
|
||||
echo '<html><body>';
|
||||
|
||||
$script = "
|
||||
<script type=\"text/javascript\">
|
||||
//<![CDATA[
|
||||
if(window != top){
|
||||
top.location.href = '{$url}';
|
||||
}
|
||||
//]]
|
||||
</script>
|
||||
";
|
||||
|
||||
$noscript = "
|
||||
<noscript>
|
||||
{$clickhere}
|
||||
</noscript>
|
||||
";
|
||||
|
||||
echo $script;
|
||||
echo $noscript;
|
||||
|
||||
echo '</body></html>';
|
||||
|
||||
}
|
@ -101,6 +101,7 @@ class mod_lti_edit_types_form extends moodleform{
|
||||
$mform->addElement('textarea', 'lti_customparameters', get_string('custom', 'lti'), array('rows' => 4, 'cols' => 60));
|
||||
$mform->setType('lti_customparameters', PARAM_TEXT);
|
||||
$mform->addHelpButton('lti_customparameters', 'custom', 'lti');
|
||||
$mform->setAdvanced('lti_customparameters');
|
||||
|
||||
if (!empty($this->_customdata->isadmin)) {
|
||||
$options = array(
|
||||
@ -136,6 +137,14 @@ class mod_lti_edit_types_form extends moodleform{
|
||||
$mform->setDefault('lti_launchcontainer', LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS);
|
||||
$mform->addHelpButton('lti_launchcontainer', 'default_launch_container', 'lti');
|
||||
$mform->setType('lti_launchcontainer', PARAM_INT);
|
||||
$mform->setAdvanced('lti_launchcontainer');
|
||||
|
||||
$mform->addElement('checkbox', 'lti_contentitem', ' ', ' ' . get_string('contentitem', 'lti'));
|
||||
$mform->addHelpButton('lti_contentitem', 'contentitem', 'lti');
|
||||
$mform->setAdvanced('lti_contentitem');
|
||||
if ($istool) {
|
||||
$mform->disabledIf('lti_contentitem', null);
|
||||
}
|
||||
|
||||
$mform->addElement('hidden', 'oldicon');
|
||||
$mform->setType('oldicon', PARAM_URL);
|
||||
|
@ -107,6 +107,10 @@ $string['configured'] = 'Configured';
|
||||
$string['confirmtoolactivation'] = 'Are you sure you would like to activate this tool?';
|
||||
$string['courseactivitiesorresources'] = 'Course activities or resources';
|
||||
$string['course_tool_types'] = 'Course tools';
|
||||
$string['configure_item'] = 'Configure item';
|
||||
$string['contentitem'] = 'Tool supports Content-Item message';
|
||||
$string['contentitem_help'] = 'If selected, the tool provider will participate in the creation of new links added to courses.';
|
||||
$string['course_tool_types'] = 'Course tool types';
|
||||
$string['courseid'] = 'Course ID number';
|
||||
$string['courseinformation'] = 'Course information';
|
||||
$string['courselink'] = 'Go to course';
|
||||
|
@ -376,18 +376,7 @@ function lti_build_request($instance, $typeconfig, $course, $typeid = null, $isl
|
||||
|
||||
$role = lti_get_ims_role($USER, $instance->cmid, $instance->course, $islti2);
|
||||
|
||||
$intro = '';
|
||||
if (!empty($instance->cmid)) {
|
||||
$intro = format_module_intro('lti', $instance, $instance->cmid);
|
||||
$intro = html_to_text($intro, 0, false);
|
||||
|
||||
// This may look weird, but this is required for new lines
|
||||
// so we generate the same OAuth signature as the tool provider.
|
||||
$intro = str_replace("\n", "\r\n", $intro);
|
||||
}
|
||||
$requestparams = array(
|
||||
'resource_link_title' => $instance->name,
|
||||
'resource_link_description' => $intro,
|
||||
'user_id' => $USER->id,
|
||||
'lis_person_sourcedid' => $USER->idnumber,
|
||||
'roles' => $role,
|
||||
@ -395,6 +384,29 @@ function lti_build_request($instance, $typeconfig, $course, $typeid = null, $isl
|
||||
'context_label' => $course->shortname,
|
||||
'context_title' => $course->fullname,
|
||||
);
|
||||
if (!empty($instance->name)) {
|
||||
$requestparams['resource_link_title'] = $instance->name;
|
||||
}
|
||||
if (!empty($instance->cmid)) {
|
||||
$intro = format_module_intro('lti', $instance, $instance->cmid);
|
||||
$intro = html_to_text($intro, 0, false);
|
||||
|
||||
// This may look weird, but this is required for new lines
|
||||
// so we generate the same OAuth signature as the tool provider.
|
||||
$intro = str_replace("\n", "\r\n", $intro);
|
||||
$requestparams['resource_link_description'] = $intro;
|
||||
}
|
||||
if (!empty($instance->servicesalt)) {
|
||||
$placementsecret = $instance->servicesalt;
|
||||
if ( isset($placementsecret) && ($islti2 ||
|
||||
$typeconfig['acceptgrades'] == LTI_SETTING_ALWAYS ||
|
||||
($typeconfig['acceptgrades'] == LTI_SETTING_DELEGATE &&
|
||||
$instance->instructorchoiceacceptgrades == LTI_SETTING_ALWAYS))) {
|
||||
|
||||
$sourcedid = json_encode(lti_build_sourcedid($instance->id, $USER->id, $placementsecret, $typeid));
|
||||
$requestparams['lis_result_sourcedid'] = $sourcedid;
|
||||
}
|
||||
}
|
||||
if (!empty($instance->id)) {
|
||||
$requestparams['resource_link_id'] = $instance->id;
|
||||
}
|
||||
@ -407,7 +419,6 @@ function lti_build_request($instance, $typeconfig, $course, $typeid = null, $isl
|
||||
$requestparams['context_type'] = 'CourseSection';
|
||||
$requestparams['lis_course_section_sourcedid'] = $course->idnumber;
|
||||
}
|
||||
$placementsecret = $instance->servicesalt;
|
||||
|
||||
if ( !empty($instance->id) && isset($placementsecret) && ($islti2 ||
|
||||
$typeconfig['acceptgrades'] == LTI_SETTING_ALWAYS ||
|
||||
@ -492,9 +503,11 @@ function lti_build_standard_request($instance, $orgid, $islti2) {
|
||||
|
||||
$requestparams = array();
|
||||
|
||||
$requestparams['resource_link_id'] = $instance->id;
|
||||
if (property_exists($instance, 'resource_link_id') and !empty($instance->resource_link_id)) {
|
||||
$requestparams['resource_link_id'] = $instance->resource_link_id;
|
||||
if ($instance) {
|
||||
$requestparams['resource_link_id'] = $instance->id;
|
||||
if (property_exists($instance, 'resource_link_id') and !empty($instance->resource_link_id)) {
|
||||
$requestparams['resource_link_id'] = $instance->resource_link_id;
|
||||
}
|
||||
}
|
||||
|
||||
$requestparams['launch_presentation_locale'] = current_language();
|
||||
@ -560,10 +573,14 @@ function lti_build_custom_parameters($toolproxy, $tool, $instance, $params, $cus
|
||||
$tool->parameter, true), $custom);
|
||||
$settings = lti_get_tool_settings($tool->toolproxyid);
|
||||
$custom = array_merge($custom, lti_get_custom_parameters($toolproxy, $tool, $params, $settings));
|
||||
$settings = lti_get_tool_settings($tool->toolproxyid, $instance->course);
|
||||
$custom = array_merge($custom, lti_get_custom_parameters($toolproxy, $tool, $params, $settings));
|
||||
$settings = lti_get_tool_settings($tool->toolproxyid, $instance->course, $instance->id);
|
||||
$custom = array_merge($custom, lti_get_custom_parameters($toolproxy, $tool, $params, $settings));
|
||||
if (!empty($instance->course)) {
|
||||
$settings = lti_get_tool_settings($tool->toolproxyid, $instance->course);
|
||||
$custom = array_merge($custom, lti_get_custom_parameters($toolproxy, $tool, $params, $settings));
|
||||
if (!empty($instance->id)) {
|
||||
$settings = lti_get_tool_settings($tool->toolproxyid, $instance->course, $instance->id);
|
||||
$custom = array_merge($custom, lti_get_custom_parameters($toolproxy, $tool, $params, $settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $custom;
|
||||
@ -1454,6 +1471,10 @@ function lti_get_type_type_config($id) {
|
||||
$type->lti_coursevisible = $config['coursevisible'];
|
||||
}
|
||||
|
||||
if (isset($config['contentitem'])) {
|
||||
$type->lti_contentitem = $config['contentitem'];
|
||||
}
|
||||
|
||||
if (isset($config['debuglaunch'])) {
|
||||
$type->lti_debuglaunch = $config['debuglaunch'];
|
||||
}
|
||||
@ -1489,6 +1510,10 @@ function lti_prepare_type_for_save($type, $config) {
|
||||
|
||||
$type->forcessl = !empty($config->lti_forcessl) ? $config->lti_forcessl : 0;
|
||||
$config->lti_forcessl = $type->forcessl;
|
||||
if (isset($config->lti_contentitem)) {
|
||||
$type->contentitem = !empty($config->lti_contentitem) ? $config->lti_contentitem : 0;
|
||||
$config->lti_contentitem = $type->contentitem;
|
||||
}
|
||||
|
||||
$type->timemodified = time();
|
||||
|
||||
@ -2147,6 +2172,7 @@ function lti_get_capabilities() {
|
||||
|
||||
$capabilities = array(
|
||||
'basic-lti-launch-request' => '',
|
||||
'ContentItemSelectionRequest' => '',
|
||||
'Context.id' => 'context_id',
|
||||
'CourseSection.title' => 'context_title',
|
||||
'CourseSection.label' => 'context_label',
|
||||
|
@ -19,11 +19,26 @@
|
||||
* @package mod
|
||||
* @subpackage lti
|
||||
* @copyright Copyright (c) 2011 Moodlerooms Inc. (http://www.moodlerooms.com)
|
||||
* @copyright 2015 Vital Source Technologies http://vitalsource.com
|
||||
* @author Stephen Vickers
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
(function(){
|
||||
var Y;
|
||||
|
||||
var LTICIP = {
|
||||
BASE : 'base',
|
||||
};
|
||||
|
||||
var CSS = {
|
||||
PANEL : 'lti-contentitem-panel',
|
||||
HIDDEN : 'hidden',
|
||||
WRAP : 'lticip-wrap',
|
||||
HEADER : 'lticip-header',
|
||||
CLOSE : 'close',
|
||||
CONTENT : 'lticip-content',
|
||||
};
|
||||
|
||||
M.mod_lti = M.mod_lti || {};
|
||||
|
||||
M.mod_lti.LTI_SETTING_NEVER = 0;
|
||||
@ -31,6 +46,13 @@
|
||||
M.mod_lti.LTI_SETTING_DELEGATE = 2;
|
||||
|
||||
M.mod_lti.editor = {
|
||||
_base : null,
|
||||
_escCloseEvent : null,
|
||||
_headingNode : null,
|
||||
_contentNode : null,
|
||||
_toolList : null,
|
||||
_onResize : null,
|
||||
_timer : null,
|
||||
init: function(yui3, settings){
|
||||
if(yui3){
|
||||
Y = yui3;
|
||||
@ -49,6 +71,21 @@
|
||||
self.updateAutomaticToolMatch(Y.one('#id_securetoolurl'));
|
||||
};
|
||||
|
||||
var create = Y.Node.create;
|
||||
this._base = create('<div class="'+CSS.PANEL+' '+CSS.HIDDEN+'"></div>')
|
||||
.append(create('<div class="'+CSS.WRAP+'"></div>')
|
||||
.append(create('<div class="'+CSS.HEADER+' header"></div>')
|
||||
.append(create('<div class="'+CSS.CLOSE+'"></div>'))
|
||||
.append(create('<h2>'+M.util.get_string('configure_item', 'lti')+'</h2>')))
|
||||
.append(create('<div class="'+CSS.CONTENT+'">' +
|
||||
'<iframe class="id_contentitem_if" src="about:blank" style="width: 99%;"></iframe></div>'))
|
||||
);
|
||||
Y.one('.lti_contentitem').on('change', this.show, this);
|
||||
this._base.one('.'+CSS.HEADER+' .'+CSS.CLOSE).on('click', this.hide, this);
|
||||
this._headingNode = this._base.one('.'+CSS.HEADER);
|
||||
this._contentNode = this._base.one('.'+CSS.CONTENT);
|
||||
Y.one(document.body).append(this._base);
|
||||
|
||||
var typeSelector = Y.one('#id_typeid');
|
||||
typeSelector.on('change', function(e){
|
||||
updateToolMatches();
|
||||
@ -492,6 +529,69 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
contentItem: function(el){
|
||||
var opt = el.options[el.selectedIndex];
|
||||
if(opt.getAttribute('contentitem') == '1') {
|
||||
window.location.href = opt.getAttribute('contentitemurl') + '&title=' +
|
||||
encodeURIComponent(document.getElementById('id_name').value);
|
||||
}
|
||||
},
|
||||
|
||||
show : function(e) {
|
||||
var opt = e.target.get('options').item(e.target.get('selectedIndex'));
|
||||
if (opt.getAttribute('contentitem') == '1') {
|
||||
this._toolList = e.target;
|
||||
e.preventDefault();
|
||||
e.halt();
|
||||
this._timer = window.setTimeout(this.doReveal, 20000);
|
||||
this._base.removeClass(CSS.HIDDEN);
|
||||
var w = this._base.get('winWidth') * 0.8;
|
||||
var h = this._base.get('winHeight') * 0.8;
|
||||
var x = (this._base.get('winWidth') - w) / 2;
|
||||
var y = (this._base.get('winHeight') - h) / 2;
|
||||
this._base.setStyle('width', '' + w + 'px');
|
||||
this._base.setStyle('height', '' + h + 'px');
|
||||
this._base.setXY([x,y]);
|
||||
|
||||
var padding = 15; //The bottom of the iframe wasn\'t visible on some themes. Probably because of border widths, etc.
|
||||
|
||||
var viewportHeight = h - parseInt(this._headingNode.getStyle('height')) - padding;
|
||||
|
||||
this._escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
|
||||
|
||||
var url = opt.getAttribute('contentitemurl') + '&title=' +
|
||||
encodeURIComponent(Y.one('#id_name').get('value'));
|
||||
|
||||
var ifr = Y.one('.id_contentitem_if');
|
||||
ifr.setAttribute('src', url);
|
||||
ifr.on('load', this.loaded, this);
|
||||
ifr.setStyle("height", viewportHeight);
|
||||
|
||||
var frm = Y.one('.mform');
|
||||
frm.reset();
|
||||
}
|
||||
},
|
||||
|
||||
doReveal : function() {
|
||||
var el = Y.one('#id_warning');
|
||||
el.removeClass(CSS.HIDDEN);
|
||||
},
|
||||
|
||||
loaded : function() {
|
||||
window.clearTimeout(this._timer);
|
||||
},
|
||||
|
||||
hide : function(e) {
|
||||
this.loaded();
|
||||
if (this._escCloseEvent) {
|
||||
this._escCloseEvent.detach();
|
||||
this._escCloseEvent = null;
|
||||
}
|
||||
this._base.addClass(CSS.HIDDEN);
|
||||
var ifr = Y.one('.id_contentitem_if');
|
||||
ifr.setAttribute('src', 'about:blank');
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -43,6 +43,8 @@
|
||||
* @author Jordi Piguillem
|
||||
* @author Nikolas Galanis
|
||||
* @author Chris Scribner
|
||||
* @copyright 2015 Vital Source Technologies http://vitalsource.com
|
||||
* @author Stephen Vickers
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
@ -54,11 +56,12 @@ require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
class mod_lti_mod_form extends moodleform_mod {
|
||||
|
||||
public function definition() {
|
||||
global $DB, $PAGE, $OUTPUT, $USER, $COURSE;
|
||||
global $DB, $PAGE, $OUTPUT, $USER, $COURSE, $sesskey, $section;
|
||||
|
||||
if ($type = optional_param('type', false, PARAM_ALPHA)) {
|
||||
component_callback("ltisource_$type", 'add_instance_hook');
|
||||
}
|
||||
$sectionreturn = optional_param('sr', 0, PARAM_INT);
|
||||
|
||||
$this->typeid = 0;
|
||||
|
||||
@ -95,7 +98,12 @@ class mod_lti_mod_form extends moodleform_mod {
|
||||
$mform->addHelpButton('showdescriptionlaunch', 'display_description', 'lti');
|
||||
|
||||
// Tool settings.
|
||||
$tooltypes = $mform->addElement('select', 'typeid', get_string('external_tool_type', 'lti'), array());
|
||||
$attributes = array();
|
||||
if ($update = optional_param('update', false, PARAM_INT)) {
|
||||
$attributes['disabled'] = 'disabled';
|
||||
}
|
||||
$attributes['class'] = 'lti_contentitem';
|
||||
$tooltypes = $mform->addElement('select', 'typeid', get_string('external_tool_type', 'lti'), array(), $attributes);
|
||||
$typeid = optional_param('typeid', false, PARAM_INT);
|
||||
$mform->getElement('typeid')->setValue($typeid);
|
||||
$mform->addHelpButton('typeid', 'external_tool_type', 'lti');
|
||||
@ -123,6 +131,15 @@ class mod_lti_mod_form extends moodleform_mod {
|
||||
} else {
|
||||
$attributes = array();
|
||||
}
|
||||
if (!$update && $id) {
|
||||
$config = lti_get_type_config($id);
|
||||
if (isset($config['contentitem']) && $config['contentitem']) {
|
||||
$contentitemurl = new moodle_url('/mod/lti/contentitem2.php',
|
||||
array('course' => $COURSE->id, 'section' => $section, 'id' => $id, 'sr' => $sectionreturn));
|
||||
$attributes['contentitem'] = 1;
|
||||
$attributes['contentitemurl'] = $contentitemurl->out(false);
|
||||
}
|
||||
}
|
||||
|
||||
$tooltypes->addOption($type->name, $id, $attributes);
|
||||
}
|
||||
@ -247,7 +264,8 @@ class mod_lti_mod_form extends moodleform_mod {
|
||||
array('tooltypedeleted', 'lti'),
|
||||
array('tooltypenotdeleted', 'lti'),
|
||||
array('tooltypeupdated', 'lti'),
|
||||
array('forced_help', 'lti')
|
||||
array('forced_help', 'lti'),
|
||||
array('configure_item', 'lti')
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -150,7 +150,8 @@ class toolproxy extends \mod_lti\local\ltiservice\resource_base {
|
||||
if ($ok) {
|
||||
$resources = $toolproxyjson->tool_profile->resource_handler;
|
||||
foreach ($resources as $resource) {
|
||||
$found = false;
|
||||
$launchable = false;
|
||||
$messages = array();
|
||||
$tool = new \stdClass();
|
||||
|
||||
$iconinfo = null;
|
||||
@ -164,19 +165,17 @@ class toolproxy extends \mod_lti\local\ltiservice\resource_base {
|
||||
}
|
||||
|
||||
foreach ($resource->message as $message) {
|
||||
if ($message->message_type == 'basic-lti-launch-request') {
|
||||
$found = true;
|
||||
$tool->path = $message->path;
|
||||
$tool->enabled_capability = $message->enabled_capability;
|
||||
$tool->parameter = $message->parameter;
|
||||
break;
|
||||
if (($message->message_type === 'basic-lti-launch-request') ||
|
||||
($message->message_type === 'ContentItemSelectionRequest')) {
|
||||
$launchable = $launchable || ($message->message_type === 'basic-lti-launch-request');
|
||||
$messages[$message->message_type] = $message;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
if (!$launchable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tool->name = $resource->resource_name->default_value;
|
||||
$tool->messages = $messages;
|
||||
$tools[] = $tool;
|
||||
}
|
||||
$ok = count($tools) > 0;
|
||||
@ -196,17 +195,27 @@ class toolproxy extends \mod_lti\local\ltiservice\resource_base {
|
||||
$securebaseurl = $toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url;
|
||||
}
|
||||
foreach ($tools as $tool) {
|
||||
$messages = $tool->messages;
|
||||
$config = new \stdClass();
|
||||
$config->lti_toolurl = "{$baseurl}{$tool->path}";
|
||||
$config->lti_toolurl = "{$baseurl}{$messages['basic-lti-launch-request']->path}";
|
||||
$config->lti_typename = $tool->name;
|
||||
$config->lti_coursevisible = 1;
|
||||
$config->lti_forcessl = 0;
|
||||
if (isset($messages['ContentItemSelectionRequest'])) {
|
||||
$config->lti_contentitem = 1;
|
||||
if ($messages['basic-lti-launch-request']->path !== $messages['ContentItemSelectionRequest']->path) {
|
||||
$config->lti_toolurl_ContentItemSelectionRequest =
|
||||
"{$baseurl}{$messages['ContentItemSelectionRequest']->path}";
|
||||
}
|
||||
$config->lti_enabledcapability_ContentItemSelectionRequest = implode("\n", $messages['ContentItemSelectionRequest']->enabled_capability);
|
||||
$config->lti_parameter_ContentItemSelectionRequest = self::lti_extract_parameters($messages['ContentItemSelectionRequest']->parameter);
|
||||
}
|
||||
|
||||
$type = new \stdClass();
|
||||
$type->state = LTI_TOOL_STATE_PENDING;
|
||||
$type->toolproxyid = $toolproxy->id;
|
||||
$type->enabledcapability = implode("\n", $tool->enabled_capability);
|
||||
$type->parameter = self::lti_extract_parameters($tool->parameter);
|
||||
$type->enabledcapability = implode("\n", $messages['basic-lti-launch-request']->enabled_capability);
|
||||
$type->parameter = self::lti_extract_parameters($messages['basic-lti-launch-request']->parameter);
|
||||
|
||||
if (!empty($tool->iconpath)) {
|
||||
$type->icon = "{$baseurl}{$tool->iconpath}";
|
||||
|
@ -380,3 +380,21 @@
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Styles for mod_form.php to support Content-Item */
|
||||
.lti-contentitem-panel {width:400px;background-color:#666;position:absolute;top:10%;left:10%;border:1px solid #666;border-width:0 5px 5px 0;}
|
||||
.lti-contentitem-panel.hidden {display:none;}
|
||||
.lti-contentitem-panel .lticip-wrap {margin-top:-5px;margin-left:-5px;background-color:#FFF;border:1px solid #999;height:inherit;}
|
||||
|
||||
.lti-contentitem-panel .lticip-header {background-color:#eee;padding:1px;}
|
||||
.lti-contentitem-panel .lticip-header h2 {margin:3px 1em 0.5em 1em;font-size:1em;}
|
||||
.lti-contentitem-panel .lticip-header .close {width:25px;height:15px;position:absolute;top:2px;right:1em;cursor:pointer;background:url("../../../../mod/lti/pix/close.png") no-repeat scroll 0 0 transparent;}
|
||||
|
||||
.lti-contentitem-panel .lticip-content {text-align:center;position:relative;width:100%;border-top:1px solid #999;border-bottom:1px solid #999;}
|
||||
.lti-contentitem-panel .lticip-ajax-content {overflow:auto;}
|
||||
|
||||
.lti-contentitem-panel .lticip-loading-lightbox {position:absolute;width:100%;height:100%;top:0;left:0;background-color:#FFF;min-width:50px;min-height:50px;}
|
||||
.lti-contentitem-panel .lticip-loading-lightbox.hidden {display:none;}
|
||||
.lti-contentitem-panel .lticip-loading-lightbox .loading-icon {margin:auto;vertical-align:middle;margin-top:125px;}
|
||||
|
||||
.dir-rtl .lti-contentitem-panel .lticip-header .close {right: auto;left:1em;}
|
||||
|
Loading…
x
Reference in New Issue
Block a user