mirror of
https://github.com/moodle/moodle.git
synced 2025-04-20 16:04:25 +02:00
Merge branch 'MDL-52154-master-wip2' of https://github.com/xow/moodle
This commit is contained in:
commit
5ea0c56236
@ -48,38 +48,42 @@ switch ($action) {
|
||||
require_capability('moodle/course:manageactivities', $context);
|
||||
require_capability('mod/lti:addinstance', $context);
|
||||
|
||||
if (empty($toolid) && !empty($toolurl)) {
|
||||
$tool = lti_get_tool_by_url_match($toolurl, $courseid);
|
||||
|
||||
if (!empty($tool)) {
|
||||
$toolid = $tool->id;
|
||||
|
||||
$response->toolid = $tool->id;
|
||||
$response->toolname = s($tool->name);
|
||||
$response->tooldomain = s($tool->tooldomain);
|
||||
}
|
||||
if (!empty($toolurl) && lti_is_cartridge($toolurl)) {
|
||||
$response->cartridge = true;
|
||||
} else {
|
||||
$response->toolid = $toolid;
|
||||
}
|
||||
if (empty($toolid) && !empty($toolurl)) {
|
||||
$tool = lti_get_tool_by_url_match($toolurl, $courseid);
|
||||
|
||||
if (!empty($toolid)) {
|
||||
// Look up privacy settings.
|
||||
$query = '
|
||||
SELECT name, value
|
||||
FROM {lti_types_config}
|
||||
WHERE
|
||||
typeid = :typeid
|
||||
AND name IN (\'sendname\', \'sendemailaddr\', \'acceptgrades\')
|
||||
';
|
||||
if (!empty($tool)) {
|
||||
$toolid = $tool->id;
|
||||
|
||||
$privacyconfigs = $DB->get_records_sql($query, array('typeid' => $toolid));
|
||||
$success = count($privacyconfigs) > 0;
|
||||
foreach ($privacyconfigs as $config) {
|
||||
$configname = $config->name;
|
||||
$response->$configname = $config->value;
|
||||
$response->toolid = $tool->id;
|
||||
$response->toolname = s($tool->name);
|
||||
$response->tooldomain = s($tool->tooldomain);
|
||||
}
|
||||
} else {
|
||||
$response->toolid = $toolid;
|
||||
}
|
||||
if (!$success) {
|
||||
$response->error = s(get_string('tool_config_not_found', 'mod_lti'));
|
||||
|
||||
if (!empty($toolid)) {
|
||||
// Look up privacy settings.
|
||||
$query = '
|
||||
SELECT name, value
|
||||
FROM {lti_types_config}
|
||||
WHERE
|
||||
typeid = :typeid
|
||||
AND name IN (\'sendname\', \'sendemailaddr\', \'acceptgrades\')
|
||||
';
|
||||
|
||||
$privacyconfigs = $DB->get_records_sql($query, array('typeid' => $toolid));
|
||||
$success = count($privacyconfigs) > 0;
|
||||
foreach ($privacyconfigs as $config) {
|
||||
$configname = $config->name;
|
||||
$response->$configname = $config->value;
|
||||
}
|
||||
if (!$success) {
|
||||
$response->error = s(get_string('tool_config_not_found', 'mod_lti'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
1
mod/lti/amd/build/cartridge_registration_form.min.js
vendored
Normal file
1
mod/lti/amd/build/cartridge_registration_form.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/ajax","core/notification","mod_lti/tool_type","mod_lti/events","mod_lti/keys","core/str"],function(a,b,c,d,e,f,g){var h={CARTRIDGE_URL:"#cartridge-url",CONSUMER_KEY:"#registration-key",SHARED_SECRET:"#registration-secret",REGISTRATION_FORM:"#cartridge-registration-form",REGISTRATION_SUBMIT_BUTTON:"#cartridge-registration-submit",REGISTRATION_CANCEL_BUTTON:"#cartridge-registration-cancel"},i=function(){return a(h.REGISTRATION_FORM).attr("data-cartridge-url")},j=function(){return a(h.REGISTRATION_SUBMIT_BUTTON)},k=function(){return a(h.REGISTRATION_CANCEL_BUTTON)},l=function(){return a(h.CONSUMER_KEY).val()},m=function(){return a(h.SHARED_SECRET).val()},n=function(){j().addClass("loading")},o=function(){j().removeClass("loading")},p=function(){return j().hasClass("loading")},q=function(){if(!p()){var b=i();if(""!==b){n();var f=l(),h=m(),j=d.create({cartridgeurl:b,key:f,secret:h});return j.done(function(){g.get_strings([{key:"success",component:"moodle"},{key:"successfullycreatedtooltype",component:"mod_lti"}]).done(function(b){a(document).trigger(e.NEW_TOOL_TYPE),a(document).trigger(e.STOP_CARTRIDGE_REGISTRATION),a(document).trigger(e.REGISTRATION_FEEDBACK,{status:b[0],message:b[1]})}).fail(c.exception)}).fail(function(){g.get_strings([{key:"error",component:"moodle"},{key:"failedtocreatetooltype",component:"mod_lti"}]).done(function(b){a(document).trigger(e.NEW_TOOL_TYPE),a(document).trigger(e.STOP_CARTRIDGE_REGISTRATION),a(document).trigger(e.REGISTRATION_FEEDBACK,{status:b[0],message:b[1],error:!0})}).fail(c.exception)}).always(function(){o()}),j}}},r=function(){var b=a(h.REGISTRATION_FORM);b.submit(function(a){a.preventDefault(),q()});var c=k();c.click(function(b){b.preventDefault(),a(document).trigger(e.STOP_CARTRIDGE_REGISTRATION)}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==f.ENTER||a.keyCode==f.SPACE)&&(a.preventDefault(),c.click())})};return{init:function(){r()}}});
|
1
mod/lti/amd/build/events.min.js
vendored
Normal file
1
mod/lti/amd/build/events.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define([],function(){return{NEW_TOOL_TYPE:"lti.tool.type.new",START_EXTERNAL_REGISTRATION:"lti.registration.external.start",STOP_EXTERNAL_REGISTRATION:"lti.registration.external.stop",START_CARTRIDGE_REGISTRATION:"lti.registration.cartridge.start",STOP_CARTRIDGE_REGISTRATION:"lti.registration.cartridge.stop",REGISTRATION_FEEDBACK:"lti.registration.feedback",CAPABILITIES_AGREE:"lti.tool.type.capabilities.agree",CAPABILITIES_DECLINE:"lti.tool.type.capabilities.decline"}});
|
1
mod/lti/amd/build/external_registration.min.js
vendored
Normal file
1
mod/lti/amd/build/external_registration.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/tool_proxy","mod_lti/tool_type","mod_lti/keys","core/str"],function(a,b,c,d,e,f,g,h,i){var j={REGISTRATION_URL:"#external-registration-url",EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-page-container",EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER:"#external-registration-template-container",EXTERNAL_REGISTRATION_CANCEL_BUTTON:"#cancel-external-registration",TOOL_TYPE_CAPABILITIES_CONTAINER:"#tool-type-capabilities-container",TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER:"#tool-type-capabilities-template-container",CAPABILITIES_AGREE_CONTAINER:".capabilities-container"},k=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER).attr("data-registration-url")},l=function(){return a(j.EXTERNAL_REGISTRATION_CANCEL_BUTTON)},m=function(){return a(j.EXTERNAL_REGISTRATION_CONTAINER)},n=function(){return a(j.EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER)},o=function(){return a(j.TOOL_TYPE_CAPABILITIES_CONTAINER)},p=function(){return a(j.TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER)},q=function(){o().addClass("loading")},r=function(){o().removeClass("loading")},s=function(){l().addClass("loading")},t=function(){l().removeClass("loading")},u=function(){o().addClass("hidden")},v=function(){o().removeClass("hidden")},w=function(){m().addClass("hidden")},x=function(){m().removeClass("hidden")},y=function(a){var b=l();b.attr("data-tool-proxy-id",a)},z=function(){var a=l();return a.attr("data-tool-proxy-id")},A=function(){var a=l();a.removeAttr("data-tool-proxy-id")},B=function(){return z()?!0:!1},C=function(a){var c={methodname:"mod_lti_get_tool_proxy_registration_request",args:{id:a}};return b.call([c])[0]},D=function(){s();var b=a.Deferred();if(B()){var d=z();f["delete"](d).done(function(){b.resolve()}).fail(function(a){b.reject(a)})}else b.resolve();return b.done(function(){I(),t()}).fail(function(b){c.exception(b),I(),t(),i.get_strings([{key:"error",component:"moodle"},{key:"failedtodeletetoolproxy",component:"mod_lti"}]).done(function(b){var c={status:b[0],message:b[1],error:!0};a(document).trigger(e.REGISTRATION_FEEDBACK,c)}).fail(c.exception)}),b},E=function(a){var b=d.render("mod_lti/tool_proxy_registration_form",a);return b.done(function(a,b){var c=n();c.append(a),d.runTemplateJS(b),c.find("form").submit(),x()}).fail(c.exception),b},F=function(a){return g.update({id:a.id,state:g.constants.state.configured})},G=function(b){var f=a.Deferred();return d.render("mod_lti/tool_type_capabilities_agree",b).done(function(a,c){var g=p();w(),v(),d.replaceNodeContents(g,a,c);var h=g.find(j.CAPABILITIES_AGREE_CONTAINER);h.on(e.CAPABILITIES_AGREE,function(){q(),F(b).always(function(){r(),g.empty(),f.resolve()})}),h.on(e.CAPABILITIES_DECLINE,function(){g.empty(),f.resolve()})}).fail(f.reject),f.done(function(){u()}).fail(c.exception),f},H=function(){var b=a.Deferred(),c=k();return""===c?b.resolve():f.create({regurl:c}).done(function(a){var c=a.id,d=a.regurl;y(c),C(c).done(function(a){a.reg_url=d,E(a).done(function(){b.resolve()}).fail(b.fail)}).fail(b.fail)}).fail(function(c){D(),a(document).trigger(e.REGISTRATION_FEEDBACK,{status:"error",message:c.message,error:!0}),b.reject(c)}),b},I=function(){B()&&A(),w();var b=n();b.empty(),a(document).trigger(e.STOP_EXTERNAL_REGISTRATION)},J=function(){a(document).on(e.START_EXTERNAL_REGISTRATION,function(){H()});var b=l();b.click(function(a){a.preventDefault(),D()}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==h.ENTER||a.keyCode==h.SPACE)&&(a.preventDefault(),D())}),window.triggerExternalRegistrationComplete=function(b){var d=a.Deferred(),f={status:b.status,message:"",error:!1};if("success"==b.status){if(i.get_strings([{key:"success",component:"moodle"},{key:"successfullycreatedtooltype",component:"mod_lti"}]).done(function(a){f.status=a[0],f.message=a[1]}).fail(c.exception),d.done(function(){I(),a(document).trigger(e.REGISTRATION_FEEDBACK,f),a(document).trigger(e.NEW_TOOL_TYPE)}).fail(c.exception),B()){var h=z();g.getFromToolProxyId(h).done(function(a){if(a&&a.length){var b=a[0];b.hascapabilitygroups?G(b).always(function(){d.resolve()}):d.resolve()}else d.resolve()}).fail(function(){d.resolve()})}}else f.message=b.error,f.error=!0,d.done(function(){D().always(function(){a(document).trigger(e.REGISTRATION_FEEDBACK,f)})}).fail(c.exception),d.resolve();return d}};return{init:function(){J()}}});
|
1
mod/lti/amd/build/external_registration_return.min.js
vendored
Normal file
1
mod/lti/amd/build/external_registration_return.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define([],function(){return{init:function(a,b,c,d){window.parent&&window.parent.triggerExternalRegistrationComplete({message:a,error:b,id:c,status:d})}}});
|
1
mod/lti/amd/build/keys.min.js
vendored
Normal file
1
mod/lti/amd/build/keys.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define([],function(){return{ENTER:13,SPACE:32}});
|
1
mod/lti/amd/build/tool_card_controller.min.js
vendored
Normal file
1
mod/lti/amd/build/tool_card_controller.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/tool_type","mod_lti/events","mod_lti/keys"],function(a,b,c,d,e,f,g){var h={DELETE_BUTTON:".delete",NAME_ELEMENT:".name",DESCRIPTION_ELEMENT:".description",CAPABILITIES_CONTAINER:".capabilities-container",ACTIVATE_BUTTON:".tool-card-footer a.activate"},i=2e3,j=function(a){return a.find(h.DELETE_BUTTON)},k=function(a){return a.find(h.NAME_ELEMENT)},l=function(a){return a.find(h.DESCRIPTION_ELEMENT)},m=function(a){return a.find(h.ACTIVATE_BUTTON)},n=function(a){return m(a).length?!0:!1},o=function(a){return a.find(h.CAPABILITIES_CONTAINER)},p=function(a){return o(a).length?!0:!1},q=function(a){return a.attr("data-type-id")},r=function(a){a.removeClass("announcement loading success fail capabilities")},s=function(a){r(a),a.addClass("announcement loading")},t=function(a){a.removeClass("announcement loading")},u=function(b){var c=a.Deferred();return r(b),b.addClass("announcement success"),setTimeout(function(){b.removeClass("announcement success"),c.resolve()},i),c},v=function(b){var c=a.Deferred();return r(b),b.addClass("announcement fail"),setTimeout(function(){b.removeClass("announcement fail"),c.resolve()},i),c},w=function(b){var d=q(b);if(""===d)return a.Deferred().resolve();s(b);var f=e["delete"](d);return f.done(function(){t(b),u(b).done(function(){b.remove()}).fail(c.exception)}),f.fail(function(){v(b)}),f},x=function(a,b){a.attr("data-val-snapshot",b)},y=function(a){return a.attr("data-val-snapshot")},z=function(a){var b=l(a);if(!b.hasClass("loading")){var c=b.text().trim();x(b,c)}},A=function(b){var d=q(b);if(""===d)return a.Deferred().resolve();var f=l(b);if(f.hasClass("loading"))return a.Deferred().resolve();var g=f.text().trim(),h=y(f);if(h==g)return a.Deferred().resolve();f.addClass("loading");var i=e.update({id:d,description:g});return i.done(function(a){f.removeClass("loading"),f.text(a.description)}).fail(c.exception),i.fail(function(){f.removeClass("loading")}),i},B=function(a){var b=k(a);if(!b.hasClass("loading")){var c=b.text().trim();x(b,c)}},C=function(b){var c=q(b);if(""===c)return a.Deferred().resolve();var d=k(b);if(d.hasClass("loading"))return a.Deferred().resolve();var f=d.text().trim(),g=y(d);if(g==f)return a.Deferred().resolve();d.addClass("loading");var h=e.update({id:c,name:f});return h.done(function(a){d.removeClass("loading"),d.text(a.name)}),h.fail(function(){d.removeClass("loading")}),h},D=function(b){var c=q(b);if(""===c)return a.Deferred().resolve();s(b);var f=e.update({id:c,state:e.constants.state.configured});return f.done(function(c){t(b);var e=u(b),f=d.render("mod_lti/tool_card",c);a.when(f,e).then(function(a){var c=a[0],e=a[1];d.replaceNode(b,c,e)})}),f.fail(function(){t(b),v(b)}),f},E=function(a){a.addClass("announcement capabilities")},F=function(a){a.removeClass("announcement capabilities")},G=function(a){p(a)?E(a):D(a)},H=function(a){var b=j(a);b.click(function(b){b.preventDefault(),w(a)}),b.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),b.click())});var c=l(a);c.focus(function(b){b.preventDefault(),z(a)}),c.blur(function(b){b.preventDefault(),A(a)}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||a.keyCode==g.ENTER&&(a.preventDefault(),c.blur())});var d=k(a);if(d.focus(function(b){b.preventDefault(),B(a)}),d.blur(function(b){b.preventDefault(),C(a)}),d.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||a.keyCode==g.ENTER&&(a.preventDefault(),d.blur())}),n(a)){var e=m(a);e.click(function(b){b.preventDefault(),G(a)}),e.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==g.ENTER||a.keyCode==g.SPACE)&&(a.preventDefault(),e.click())})}if(p(a)){var h=o(a);h.on(f.CAPABILITIES_AGREE,function(){D(a)}),h.on(f.CAPABILITIES_DECLINE,function(){F(a)})}};return{init:function(a){H(a)}}});
|
1
mod/lti/amd/build/tool_configure_controller.min.js
vendored
Normal file
1
mod/lti/amd/build/tool_configure_controller.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/ajax","core/notification","core/templates","mod_lti/events","mod_lti/keys","mod_lti/tool_type"],function(a,b,c,d,e,f,g){var h={REGISTRATION_FEEDBACK_CONTAINER:"#registration-feedback-container",EXTERNAL_REGISTRATION_CONTAINER:"#external-registration-container",EXTERNAL_REGISTRATION_PAGE_CONTAINER:"#external-registration-page-container",CARTRIDGE_REGISTRATION_CONTAINER:"#cartridge-registration-container",CARTRIDGE_REGISTRATION_FORM:"#cartridge-registration-form",ADD_TOOL_FORM:"#add-tool-form",TOOL_LIST_CONTAINER:"#tool-list-container",TOOL_CREATE_BUTTON:"#tool-create-button",REGISTRATION_CHOICE_CONTAINER:"#registration-choice-container",TOOL_URL:"#tool-url"},i=function(){return a(h.TOOL_CREATE_BUTTON)},j=function(){return a(h.REGISTRATION_FEEDBACK_CONTAINER)},k=function(){return a(h.TOOL_LIST_CONTAINER)},l=function(){return a(h.EXTERNAL_REGISTRATION_CONTAINER)},m=function(){return a(h.CARTRIDGE_REGISTRATION_CONTAINER)},n=function(){return a(h.REGISTRATION_CHOICE_CONTAINER)},o=function(){return a(h.TOOL_URL).val()},p=function(){l().addClass("hidden")},q=function(){m().addClass("hidden")},r=function(){n().addClass("hidden")},s=function(a){q(),r(),l().removeClass("hidden"),l().find(h.EXTERNAL_REGISTRATION_PAGE_CONTAINER).attr("data-registration-url",a),u(l())},t=function(a){p(),r(),m().removeClass("hidden"),m().find(h.CARTRIDGE_REGISTRATION_FORM).attr("data-cartridge-url",a),u(m())},u=function(a){var b=a.children().clone(!0,!0);a.empty(),a.append(b)},v=function(){y()||(p(),q(),n().removeClass("hidden"),u(n()))},w=function(){k().addClass("hidden")},x=function(){k().removeClass("hidden")},y=function(){return a.trim(j().html())},z=function(a){d.render("mod_lti/registration_feedback",a).done(function(a){p(),q(),r();var b=j();b.append(a)}).fail(c.exception)},A=function(){var a=j();a.empty(),v()},B=function(a){a.addClass("loading")},C=function(a){a.removeClass("loading")},D=function(){var a=k();B(a),g.query().done(function(b){d.render("mod_lti/tool_list",{tools:b}).done(function(b,c){a.empty(),a.append(b),d.runTemplateJS(c)}).fail(c.exception)}).fail(c.exception).always(function(){C(a)})},E=function(){var b=o();if(""===b)return a.Deferred().resolve();var d=i();B(d);var f=g.isCartridge(b);return f.always(function(){C(d)}),f.done(function(c){c.iscartridge?(a(h.TOOL_URL).val(""),a(document).trigger(e.START_CARTRIDGE_REGISTRATION,b)):(s(b),a(h.TOOL_URL).val(""),a(document).trigger(e.START_EXTERNAL_REGISTRATION),w())}),f.fail(c.exception),f},F=function(){a(document).on(e.NEW_TOOL_TYPE,function(){D()}),a(document).on(e.STOP_EXTERNAL_REGISTRATION,function(){x(),v()}),a(document).on(e.START_CARTRIDGE_REGISTRATION,function(a,b){t(b)}),a(document).on(e.STOP_CARTRIDGE_REGISTRATION,function(){m().find(h.CARTRIDGE_REGISTRATION_FORM).removeAttr("data-cartridge-url"),v()}),a(document).on(e.REGISTRATION_FEEDBACK,function(a,b){z(b)});var b=a(h.ADD_TOOL_FORM);b.submit(function(a){a.preventDefault(),E()});var c=j();c.click(function(a){a.preventDefault(),A()}),c.keypress(function(a){a.metaKey||a.shiftKey||a.altKey||a.ctrlKey||(a.keyCode==f.ENTER||a.keyCode==f.SPACE)&&(a.preventDefault(),A())})};return{init:function(){F(),D()}}});
|
1
mod/lti/amd/build/tool_proxy.min.js
vendored
Normal file
1
mod/lti/amd/build/tool_proxy.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["core/ajax","core/notification"],function(a,b){return{"delete":function(c){var d={methodname:"mod_lti_delete_tool_proxy",args:{id:c}},e=a.call([d])[0];return e.fail(b.exception),e},create:function(c){var d={methodname:"mod_lti_create_tool_proxy",args:c},e=a.call([d])[0];return e.fail(b.exception),e}}});
|
1
mod/lti/amd/build/tool_type.min.js
vendored
Normal file
1
mod/lti/amd/build/tool_type.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["core/ajax","core/notification"],function(a,b){return{query:function(c){var d={methodname:"mod_lti_get_tool_types",args:c||{}},e=a.call([d])[0];return e.fail(b.exception),e},create:function(c){var d={methodname:"mod_lti_create_tool_type",args:c},e=a.call([d])[0];return e.fail(b.exception),e},update:function(c){var d={methodname:"mod_lti_update_tool_type",args:c},e=a.call([d])[0];return e.fail(b.exception),e},"delete":function(c){var d={methodname:"mod_lti_delete_tool_type",args:{id:c}},e=a.call([d])[0];return e.fail(b.exception),e},getFromToolProxyId:function(a){return this.query({toolproxyid:a})},isCartridge:function(c){var d={methodname:"mod_lti_is_cartridge",args:{url:c}},e=a.call([d])[0];return e.fail(b.exception),e},constants:{state:{configured:1,pending:2,rejected:3}}}});
|
218
mod/lti/amd/src/cartridge_registration_form.js
Normal file
218
mod/lti/amd/src/cartridge_registration_form.js
Normal file
@ -0,0 +1,218 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Encapsules the behavior for creating a tool type from a cartridge URL
|
||||
* in Moodle. Manages the UI while operations are occuring.
|
||||
*
|
||||
* See template: mod_lti/cartridge_registration_form
|
||||
*
|
||||
* @module mod_lti/cartridge_registration_form
|
||||
* @class cartridge_registration_form
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['jquery', 'core/ajax', 'core/notification', 'mod_lti/tool_type', 'mod_lti/events', 'mod_lti/keys', 'core/str'],
|
||||
function($, ajax, notification, toolType, ltiEvents, KEYS, str) {
|
||||
|
||||
var SELECTORS = {
|
||||
CARTRIDGE_URL: '#cartridge-url',
|
||||
CONSUMER_KEY: '#registration-key',
|
||||
SHARED_SECRET: '#registration-secret',
|
||||
REGISTRATION_FORM: '#cartridge-registration-form',
|
||||
REGISTRATION_SUBMIT_BUTTON: '#cartridge-registration-submit',
|
||||
REGISTRATION_CANCEL_BUTTON: '#cartridge-registration-cancel',
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the URL the user entered for the cartridge.
|
||||
*
|
||||
* @method getCartridgeURL
|
||||
* @private
|
||||
* @return string
|
||||
*/
|
||||
var getCartridgeURL = function() {
|
||||
return $(SELECTORS.REGISTRATION_FORM).attr('data-cartridge-url');
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the submit button element.
|
||||
*
|
||||
* @method getSubmitButton
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getSubmitButton = function() {
|
||||
return $(SELECTORS.REGISTRATION_SUBMIT_BUTTON);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the cancel button element.
|
||||
*
|
||||
* @method getCancelButton
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getCancelButton = function() {
|
||||
return $(SELECTORS.REGISTRATION_CANCEL_BUTTON);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the value that the user entered for the consumer key.
|
||||
*
|
||||
* @method getConsumerKey
|
||||
* @private
|
||||
* @return string
|
||||
*/
|
||||
var getConsumerKey = function() {
|
||||
return $(SELECTORS.CONSUMER_KEY).val();
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the value that the user entered for the shared secret.
|
||||
*
|
||||
* @method getSharedSecret
|
||||
* @private
|
||||
* @return string
|
||||
*/
|
||||
var getSharedSecret = function() {
|
||||
return $(SELECTORS.SHARED_SECRET).val();
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger a visual loading indicator.
|
||||
*
|
||||
* @method startLoading
|
||||
* @private
|
||||
*/
|
||||
var startLoading = function() {
|
||||
getSubmitButton().addClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the visual loading indicator.
|
||||
*
|
||||
* @method stopLoading
|
||||
* @private
|
||||
*/
|
||||
var stopLoading = function() {
|
||||
getSubmitButton().removeClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the page is currently loading.
|
||||
*
|
||||
* @method isLoading
|
||||
* @private
|
||||
* @return bool
|
||||
*/
|
||||
var isLoading = function() {
|
||||
return getSubmitButton().hasClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a tool type from the cartridge URL that the user input. This will
|
||||
* send an ajax request to the Moodle server to create the Type. The request will
|
||||
* include the consumer key and secret, if any.
|
||||
*
|
||||
* On success the page will be re-rendered to take the user back to the original
|
||||
* page with the list of tools and an alert notifying them of success.
|
||||
*
|
||||
* @method submitCartridgeURL
|
||||
* @private
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
var submitCartridgeURL = function() {
|
||||
if (isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = getCartridgeURL();
|
||||
// No URL? Do nothing.
|
||||
if (url === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
startLoading();
|
||||
var consumerKey = getConsumerKey();
|
||||
var sharedSecret = getSharedSecret();
|
||||
var promise = toolType.create({cartridgeurl: url, key: consumerKey, secret: sharedSecret});
|
||||
|
||||
promise.done(function() {
|
||||
str.get_strings([{key: 'success', component: 'moodle'},
|
||||
{key: 'successfullycreatedtooltype', component: 'mod_lti'}]).done(function (s) {
|
||||
$(document).trigger(ltiEvents.NEW_TOOL_TYPE);
|
||||
$(document).trigger(ltiEvents.STOP_CARTRIDGE_REGISTRATION);
|
||||
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, {
|
||||
status: s[0],
|
||||
message: s[1]
|
||||
});
|
||||
}).fail(notification.exception);
|
||||
}).fail(function() {
|
||||
str.get_strings([{key: 'error', component: 'moodle'},
|
||||
{key: 'failedtocreatetooltype', component: 'mod_lti'}]).done(function (s) {
|
||||
$(document).trigger(ltiEvents.NEW_TOOL_TYPE);
|
||||
$(document).trigger(ltiEvents.STOP_CARTRIDGE_REGISTRATION);
|
||||
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, {
|
||||
status: s[0],
|
||||
message: s[1],
|
||||
error: true
|
||||
});
|
||||
}).fail(notification.exception);
|
||||
}).always(function() { stopLoading(); });
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up the listeners for user interaction on the page.
|
||||
*
|
||||
* @method registerEventListeners
|
||||
* @private
|
||||
*/
|
||||
var registerEventListeners = function() {
|
||||
var form = $(SELECTORS.REGISTRATION_FORM);
|
||||
form.submit(function(e) {
|
||||
e.preventDefault();
|
||||
submitCartridgeURL();
|
||||
});
|
||||
|
||||
var cancelButton = getCancelButton();
|
||||
cancelButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
$(document).trigger(ltiEvents.STOP_CARTRIDGE_REGISTRATION);
|
||||
});
|
||||
cancelButton.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
cancelButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return /** @alias module:mod_lti/cartridge_registration_form */ {
|
||||
|
||||
/**
|
||||
* Initialise this module.
|
||||
*/
|
||||
init: function() {
|
||||
registerEventListeners();
|
||||
}
|
||||
};
|
||||
});
|
38
mod/lti/amd/src/events.js
Normal file
38
mod/lti/amd/src/events.js
Normal file
@ -0,0 +1,38 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Provides a list of events that can be triggered in the LTI management
|
||||
* page.
|
||||
*
|
||||
* @module mod_lti/events
|
||||
* @class events
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define([], function() {
|
||||
return /** @alias module:mod_lti/events */ {
|
||||
NEW_TOOL_TYPE: 'lti.tool.type.new',
|
||||
START_EXTERNAL_REGISTRATION: 'lti.registration.external.start',
|
||||
STOP_EXTERNAL_REGISTRATION: 'lti.registration.external.stop',
|
||||
START_CARTRIDGE_REGISTRATION: 'lti.registration.cartridge.start',
|
||||
STOP_CARTRIDGE_REGISTRATION: 'lti.registration.cartridge.stop',
|
||||
REGISTRATION_FEEDBACK: 'lti.registration.feedback',
|
||||
CAPABILITIES_AGREE: 'lti.tool.type.capabilities.agree',
|
||||
CAPABILITIES_DECLINE: 'lti.tool.type.capabilities.decline',
|
||||
};
|
||||
});
|
594
mod/lti/amd/src/external_registration.js
Normal file
594
mod/lti/amd/src/external_registration.js
Normal file
@ -0,0 +1,594 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Encapsules the behavior for creating a tool type and tool proxy from a
|
||||
* registration url in Moodle.
|
||||
*
|
||||
* Manages the UI while operations are occuring, including rendering external
|
||||
* registration page within the iframe.
|
||||
*
|
||||
* See template: mod_lti/external_registration
|
||||
*
|
||||
* @module mod_lti/external_registration
|
||||
* @class external_registration
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/events',
|
||||
'mod_lti/tool_proxy', 'mod_lti/tool_type', 'mod_lti/keys', 'core/str'],
|
||||
function($, ajax, notification, templates, ltiEvents, toolProxy, toolType, KEYS, str) {
|
||||
|
||||
var SELECTORS = {
|
||||
REGISTRATION_URL: '#external-registration-url',
|
||||
EXTERNAL_REGISTRATION_CONTAINER: '#external-registration-page-container',
|
||||
EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER: '#external-registration-template-container',
|
||||
EXTERNAL_REGISTRATION_CANCEL_BUTTON: '#cancel-external-registration',
|
||||
TOOL_TYPE_CAPABILITIES_CONTAINER: '#tool-type-capabilities-container',
|
||||
TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER: '#tool-type-capabilities-template-container',
|
||||
CAPABILITIES_AGREE_CONTAINER: '.capabilities-container',
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the URL the user entered for the registration.
|
||||
*
|
||||
* @method getRegistrationURL
|
||||
* @private
|
||||
* @return string
|
||||
*/
|
||||
var getRegistrationURL = function() {
|
||||
return $(SELECTORS.EXTERNAL_REGISTRATION_CONTAINER).attr('data-registration-url');
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the external registration cancel button element. This button is
|
||||
* the cancel button that appears while the iframe is rendered.
|
||||
*
|
||||
* @method getExternalRegistrationCancelButton
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getExternalRegistrationCancelButton = function() {
|
||||
return $(SELECTORS.EXTERNAL_REGISTRATION_CANCEL_BUTTON);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the container that holds all elements for the external registration, including
|
||||
* the cancel button and the iframe.
|
||||
*
|
||||
* @method getExternalRegistrationContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getExternalRegistrationContainer = function() {
|
||||
return $(SELECTORS.EXTERNAL_REGISTRATION_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the container that holds the external registration page template. It should
|
||||
* be the iframe.
|
||||
*
|
||||
* @method getExternalRegistrationTemplateContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getExternalRegistrationTemplateContainer = function() {
|
||||
return $(SELECTORS.EXTERNAL_REGISTRATION_TEMPLATE_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the container that holds the elements for displaying the list of capabilities
|
||||
* that this tool type requires. This container wraps the loading indicator and the template
|
||||
* container.
|
||||
*
|
||||
* @method getToolTypeCapabilitiesContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getToolTypeCapabilitiesContainer = function() {
|
||||
return $(SELECTORS.TOOL_TYPE_CAPABILITIES_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the container that holds the template that lists the capabilities that the
|
||||
* tool type will require.
|
||||
*
|
||||
* @method getToolTypeCapabilitiesTemplateContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getToolTypeCapabilitiesTemplateContainer = function() {
|
||||
return $(SELECTORS.TOOL_TYPE_CAPABILITIES_TEMPLATE_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggers a visual indicator to show that the capabilities section is loading.
|
||||
*
|
||||
* @method startLoadingCapabilitiesContainer
|
||||
* @private
|
||||
*/
|
||||
var startLoadingCapabilitiesContainer = function() {
|
||||
getToolTypeCapabilitiesContainer().addClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the visual indicator that shows the capabilities section is loading.
|
||||
*
|
||||
* @method stopLoadingCapabilitiesContainer
|
||||
* @private
|
||||
*/
|
||||
var stopLoadingCapabilitiesContainer = function() {
|
||||
getToolTypeCapabilitiesContainer().removeClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a visual indicator that shows the cancel button is loading.
|
||||
*
|
||||
* @method startLoadingCancel
|
||||
* @private
|
||||
*/
|
||||
var startLoadingCancel = function() {
|
||||
getExternalRegistrationCancelButton().addClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a visual indicator that shows the cancel button is loading.
|
||||
*
|
||||
* @method startLoadingCancel
|
||||
* @private
|
||||
*/
|
||||
var stopLoadingCancel = function() {
|
||||
getExternalRegistrationCancelButton().removeClass('loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Stops displaying the tool type capabilities container.
|
||||
*
|
||||
* @method hideToolTypeCapabilitiesContainer
|
||||
* @private
|
||||
*/
|
||||
var hideToolTypeCapabilitiesContainer = function() {
|
||||
getToolTypeCapabilitiesContainer().addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays the tool type capabilities container.
|
||||
*
|
||||
* @method showToolTypeCapabilitiesContainer
|
||||
* @private
|
||||
*/
|
||||
var showToolTypeCapabilitiesContainer = function() {
|
||||
getToolTypeCapabilitiesContainer().removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Stops displaying the external registration content.
|
||||
*
|
||||
* @method hideExternalRegistrationContent
|
||||
* @private
|
||||
*/
|
||||
var hideExternalRegistrationContent = function() {
|
||||
getExternalRegistrationContainer().addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays the external registration content.
|
||||
*
|
||||
* @method showExternalRegistrationContent
|
||||
* @private
|
||||
*/
|
||||
var showExternalRegistrationContent = function() {
|
||||
getExternalRegistrationContainer().removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Save the given tool proxy id on the DOM.
|
||||
*
|
||||
* @method setToolProxyId
|
||||
* @private
|
||||
* @param int Tool proxy ID
|
||||
*/
|
||||
var setToolProxyId = function(id) {
|
||||
var button = getExternalRegistrationCancelButton();
|
||||
button.attr('data-tool-proxy-id', id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the saved tool proxy id.
|
||||
*
|
||||
* @method getToolProxyId
|
||||
* @private
|
||||
* @return string Tool proxy ID
|
||||
*/
|
||||
var getToolProxyId = function() {
|
||||
var button = getExternalRegistrationCancelButton();
|
||||
return button.attr('data-tool-proxy-id');
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the saved tool proxy id.
|
||||
*
|
||||
* @method clearToolProxyId
|
||||
* @private
|
||||
*/
|
||||
var clearToolProxyId = function() {
|
||||
var button = getExternalRegistrationCancelButton();
|
||||
button.removeAttr('data-tool-proxy-id');
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if this process has created a tool proxy within
|
||||
* Moodle yet.
|
||||
*
|
||||
* @method hasCreatedToolProxy
|
||||
* @private
|
||||
* @return bool
|
||||
*/
|
||||
var hasCreatedToolProxy = function() {
|
||||
return getToolProxyId() ? true : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the external registration request required to be sent to the external
|
||||
* registration page using a form.
|
||||
*
|
||||
* See mod_lti/tool_proxy_registration_form template.
|
||||
*
|
||||
* @method getRegistrationRequest
|
||||
* @private
|
||||
* @param int Tool Proxy ID
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var getRegistrationRequest = function(id) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_get_tool_proxy_registration_request',
|
||||
args: {
|
||||
id: id
|
||||
}
|
||||
};
|
||||
|
||||
return ajax.call([request])[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel an in progress external registration. This will perform any necessary
|
||||
* clean up of tool proxies and return the page section back to the home section.
|
||||
*
|
||||
* @method cancelRegistration
|
||||
* @private
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var cancelRegistration = function() {
|
||||
startLoadingCancel();
|
||||
var promise = $.Deferred();
|
||||
|
||||
// If we've created a proxy as part of this process then
|
||||
// we need to delete it to clean up the data in the back end.
|
||||
if (hasCreatedToolProxy()) {
|
||||
var id = getToolProxyId();
|
||||
toolProxy.delete(id).done(function() {
|
||||
promise.resolve();
|
||||
}).fail(function (failure) {
|
||||
promise.reject(failure);
|
||||
});
|
||||
} else {
|
||||
promise.resolve();
|
||||
}
|
||||
|
||||
promise.done(function() {
|
||||
// Return to the original page.
|
||||
finishExternalRegistration();
|
||||
stopLoadingCancel();
|
||||
}).fail(function (failure) {
|
||||
notification.exception(failure);
|
||||
finishExternalRegistration();
|
||||
stopLoadingCancel();
|
||||
str.get_strings([{key: 'error', component: 'moodle'},
|
||||
{key: 'failedtodeletetoolproxy', component: 'mod_lti'}]).done(function (s) {
|
||||
var feedback = {
|
||||
status: s[0],
|
||||
message: s[1],
|
||||
error: true
|
||||
};
|
||||
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, feedback);
|
||||
}).fail(notification.exception);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the external registration template and render it in the DOM and display it.
|
||||
*
|
||||
* @method renderExternalRegistrationWindow
|
||||
* @private
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var renderExternalRegistrationWindow = function(registrationRequest) {
|
||||
var promise = templates.render('mod_lti/tool_proxy_registration_form', registrationRequest);
|
||||
|
||||
promise.done(function(html, js) {
|
||||
// Show the external registration page in an iframe.
|
||||
var container = getExternalRegistrationTemplateContainer();
|
||||
container.append(html);
|
||||
templates.runTemplateJS(js);
|
||||
|
||||
container.find('form').submit();
|
||||
showExternalRegistrationContent();
|
||||
}).fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a request to Moodle server to set the state of the tool type to configured (active).
|
||||
*
|
||||
* @method setTypeStatusActive
|
||||
* @private
|
||||
* @param object A set of data representing a type, as returned by a request to get a type
|
||||
* from the Moodle server.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var setTypeStatusActive = function(typeData) {
|
||||
return toolType.update({
|
||||
id: typeData.id,
|
||||
state: toolType.constants.state.configured
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Render and display an agreement page for the user to acknowledge the list of capabilities
|
||||
* (groups of data) that the external tool requires in order to work. If the user agrees then
|
||||
* we will activate the tool so that it is immediately available. If they don't agree then
|
||||
* the tool remains in a pending state within Moodle until agreement is given.
|
||||
*
|
||||
* @method promptForToolTypeCapabilitiesAgreement
|
||||
* @private
|
||||
* @param object A set of data representing a type, as returned by a request to get a type
|
||||
* from the Moodle server.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var promptForToolTypeCapabilitiesAgreement = function(typeData) {
|
||||
var promise = $.Deferred();
|
||||
|
||||
templates.render('mod_lti/tool_type_capabilities_agree', typeData).done(function(html, js) {
|
||||
var container = getToolTypeCapabilitiesTemplateContainer();
|
||||
|
||||
hideExternalRegistrationContent();
|
||||
showToolTypeCapabilitiesContainer();
|
||||
|
||||
templates.replaceNodeContents(container, html, js);
|
||||
|
||||
var choiceContainer = container.find(SELECTORS.CAPABILITIES_AGREE_CONTAINER);
|
||||
|
||||
// The user agrees to allow the tool to use the groups of data so we can go
|
||||
// ahead and activate it for them so that it can be used straight away.
|
||||
choiceContainer.on(ltiEvents.CAPABILITIES_AGREE, function() {
|
||||
startLoadingCapabilitiesContainer();
|
||||
setTypeStatusActive(typeData).always(function() {
|
||||
stopLoadingCapabilitiesContainer();
|
||||
container.empty();
|
||||
promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// The user declines to let the tool use the data. In this case we leave
|
||||
// the tool as pending and they can delete it using the main screen if they
|
||||
// wish.
|
||||
choiceContainer.on(ltiEvents.CAPABILITIES_DECLINE, function() {
|
||||
container.empty();
|
||||
promise.resolve();
|
||||
});
|
||||
}).fail(promise.reject);
|
||||
|
||||
promise.done(function() {
|
||||
hideToolTypeCapabilitiesContainer();
|
||||
}).fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a request to the Moodle server to create a tool proxy using the registration URL the user
|
||||
* has provided. The proxy is required for the external registration page to work correctly.
|
||||
*
|
||||
* After the proxy is created the external registration page is rendered within an iframe for the user
|
||||
* to complete the registration in the external page.
|
||||
*
|
||||
* If the tool proxy creation fails then we redirect the page section back to the home section and
|
||||
* display the error, rather than rendering the external registration page.
|
||||
*
|
||||
* @method submitExternalRegistration
|
||||
* @private
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var submitExternalRegistration = function() {
|
||||
var promise = $.Deferred();
|
||||
var url = getRegistrationURL();
|
||||
|
||||
if (url === "") {
|
||||
// No URL has been input so do nothing.
|
||||
promise.resolve();
|
||||
} else {
|
||||
// A tool proxy needs to exists before the external page is rendered because
|
||||
// the external page sends requests back to Moodle for information that is stored
|
||||
// in the proxy.
|
||||
toolProxy.create({regurl: url}).done(function(result) {
|
||||
var id = result.id;
|
||||
var regURL = result.regurl;
|
||||
|
||||
// Save the id on the DOM to cleanup later.
|
||||
setToolProxyId(id);
|
||||
|
||||
// There is a specific set of data needed to send to the external registration page
|
||||
// in a form, so let's get it from our server.
|
||||
getRegistrationRequest(id).done(function(registrationRequest) {
|
||||
|
||||
registrationRequest.reg_url = regURL;
|
||||
renderExternalRegistrationWindow(registrationRequest).done(function() {
|
||||
|
||||
promise.resolve();
|
||||
|
||||
}).fail(promise.fail);
|
||||
|
||||
}).fail(promise.fail);
|
||||
|
||||
}).fail(function(exception) {
|
||||
// Clean up.
|
||||
cancelRegistration();
|
||||
// Let the user know what the error is.
|
||||
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, {status: 'error', message: exception.message, error: true});
|
||||
promise.reject(exception);
|
||||
});
|
||||
}
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Complete the registration process, clean up any left over data and
|
||||
* trigger the appropriate events.
|
||||
*
|
||||
* @method finishExternalRegistration
|
||||
* @private
|
||||
*/
|
||||
var finishExternalRegistration = function() {
|
||||
if (hasCreatedToolProxy()) {
|
||||
clearToolProxyId();
|
||||
}
|
||||
|
||||
hideExternalRegistrationContent();
|
||||
var container = getExternalRegistrationTemplateContainer();
|
||||
container.empty();
|
||||
|
||||
$(document).trigger(ltiEvents.STOP_EXTERNAL_REGISTRATION);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up the listeners for user interaction on the page.
|
||||
*
|
||||
* @method registerEventListeners
|
||||
* @private
|
||||
*/
|
||||
var registerEventListeners = function() {
|
||||
|
||||
$(document).on(ltiEvents.START_EXTERNAL_REGISTRATION, function() {
|
||||
submitExternalRegistration();
|
||||
});
|
||||
|
||||
var cancelExternalRegistrationButton = getExternalRegistrationCancelButton();
|
||||
cancelExternalRegistrationButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
cancelRegistration();
|
||||
});
|
||||
cancelExternalRegistrationButton.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
cancelRegistration();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This is gross but necessary due to isolated jQuery scopes between
|
||||
// child iframe and parent windows. There is no other way to communicate.
|
||||
//
|
||||
// This function gets called by the moodle page that received the redirect
|
||||
// from the external registration page and handles the external page's returned
|
||||
// parameters.
|
||||
//
|
||||
// See AMD module mod_lti/external_registration_return.
|
||||
window.triggerExternalRegistrationComplete = function(data) {
|
||||
var promise = $.Deferred();
|
||||
var feedback = {
|
||||
status: data.status,
|
||||
message: "",
|
||||
error: false
|
||||
};
|
||||
|
||||
if (data.status == "success") {
|
||||
str.get_strings([{key: 'success', component: 'moodle'},
|
||||
{key: 'successfullycreatedtooltype', component: 'mod_lti'}]).done(function (s) {
|
||||
feedback.status = s[0];
|
||||
feedback.message = s[1];
|
||||
}).fail(notification.exception);
|
||||
|
||||
// Trigger appropriate events when we've completed the necessary requests.
|
||||
promise.done(function() {
|
||||
finishExternalRegistration();
|
||||
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, feedback);
|
||||
$(document).trigger(ltiEvents.NEW_TOOL_TYPE);
|
||||
}).fail(notification.exception);
|
||||
|
||||
// We should have created a tool proxy by this point.
|
||||
if (hasCreatedToolProxy()) {
|
||||
var proxyId = getToolProxyId();
|
||||
|
||||
// We need the list of types that are linked to this proxy. We're assuming it'll
|
||||
// only be one because this process creates a one-to-one type->proxy.
|
||||
toolType.getFromToolProxyId(proxyId).done(function(types) {
|
||||
if (types && types.length) {
|
||||
// There should only be one result.
|
||||
var typeData = types[0];
|
||||
|
||||
// Check if the external tool required access to any Moodle data (users, courses etc).
|
||||
if (typeData.hascapabilitygroups) {
|
||||
// If it did then we ask the user to agree to those groups before the type is
|
||||
// activated (i.e. can be used in Moodle).
|
||||
promptForToolTypeCapabilitiesAgreement(typeData).always(function() {
|
||||
promise.resolve();
|
||||
});
|
||||
} else {
|
||||
promise.resolve();
|
||||
}
|
||||
} else {
|
||||
promise.resolve();
|
||||
}
|
||||
}).fail(function() {
|
||||
promise.resolve();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Anything other than success is failure.
|
||||
feedback.message = data.error;
|
||||
feedback.error = true;
|
||||
|
||||
// Cancel registration to clean up any proxies and tools that were
|
||||
// created.
|
||||
promise.done(function() {
|
||||
cancelRegistration().always(function() {
|
||||
$(document).trigger(ltiEvents.REGISTRATION_FEEDBACK, feedback);
|
||||
});
|
||||
}).fail(notification.exception);
|
||||
|
||||
promise.resolve();
|
||||
}
|
||||
|
||||
return promise;
|
||||
};
|
||||
};
|
||||
|
||||
return /** @alias module:mod_lti/external_registration */ {
|
||||
|
||||
/**
|
||||
* Initialise this module.
|
||||
*/
|
||||
init: function() {
|
||||
registerEventListeners();
|
||||
}
|
||||
};
|
||||
});
|
55
mod/lti/amd/src/external_registration_return.js
Normal file
55
mod/lti/amd/src/external_registration_return.js
Normal file
@ -0,0 +1,55 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Handles the return params from the external registration page after it
|
||||
* redirects back to Moodle.
|
||||
*
|
||||
* See also: mod/lti/externalregistrationreturn.php
|
||||
*
|
||||
* @module mod_lti/external_registration_return
|
||||
* @class external_registration_return
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define([], function() {
|
||||
|
||||
return /** @alias module:mod_lti/external_registration_return */ {
|
||||
|
||||
/**
|
||||
* If this was rendered in an iframe then trigger the external registration
|
||||
* complete behaviour in the parent page and provide the params returned from
|
||||
* the external registration page.
|
||||
*
|
||||
* @param string message The registration message from the external registration page
|
||||
* @param string error The registration error message from the external registration page, if
|
||||
* there was an error.
|
||||
* @param int id The tool proxy id for the external registration.
|
||||
* @param string status Whether the external registration was successful or not.
|
||||
*/
|
||||
init: function(message, error, id, status) {
|
||||
if (window.parent) {
|
||||
window.parent.triggerExternalRegistrationComplete({
|
||||
message: message,
|
||||
error: error,
|
||||
id: id,
|
||||
status: status
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
31
mod/lti/amd/src/keys.js
Normal file
31
mod/lti/amd/src/keys.js
Normal file
@ -0,0 +1,31 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* A list of keys and their keycodes that are used by the LTI modules.
|
||||
*
|
||||
* @module mod_lti/keys
|
||||
* @class keys
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define([], function() {
|
||||
return /** @alias module:mod_lti/keys */ {
|
||||
ENTER: 13,
|
||||
SPACE: 32
|
||||
};
|
||||
});
|
604
mod/lti/amd/src/tool_card_controller.js
Normal file
604
mod/lti/amd/src/tool_card_controller.js
Normal file
@ -0,0 +1,604 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls all of the behaviour and interaction with a tool type card. These are
|
||||
* listed on the LTI tool type management page.
|
||||
*
|
||||
* See template: mod_lti/tool_card
|
||||
*
|
||||
* @module mod_lti/tool_card_controller
|
||||
* @class tool_card_controller
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/tool_type', 'mod_lti/events', 'mod_lti/keys'],
|
||||
function($, ajax, notification, templates, toolType, ltiEvents, KEYS) {
|
||||
|
||||
var SELECTORS = {
|
||||
DELETE_BUTTON: '.delete',
|
||||
NAME_ELEMENT: '.name',
|
||||
DESCRIPTION_ELEMENT: '.description',
|
||||
CAPABILITIES_CONTAINER: '.capabilities-container',
|
||||
ACTIVATE_BUTTON: '.tool-card-footer a.activate',
|
||||
};
|
||||
|
||||
// Timeout in seconds.
|
||||
var ANNOUNCEMENT_TIMEOUT = 2000;
|
||||
|
||||
/**
|
||||
* Return the delete button element.
|
||||
*
|
||||
* @method getDeleteButton
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getDeleteButton = function(element) {
|
||||
return element.find(SELECTORS.DELETE_BUTTON);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the element representing the tool type name.
|
||||
*
|
||||
* @method getNameElement
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getNameElement = function(element) {
|
||||
return element.find(SELECTORS.NAME_ELEMENT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the element representing the tool type description.
|
||||
*
|
||||
* @method getDescriptionElement
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getDescriptionElement = function(element) {
|
||||
return element.find(SELECTORS.DESCRIPTION_ELEMENT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the activate button for the type.
|
||||
*
|
||||
* @method getActivateButton
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getActivateButton = function(element) {
|
||||
return element.find(SELECTORS.ACTIVATE_BUTTON);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the type card has an activate button.
|
||||
*
|
||||
* @method hasActivateButton
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return bool
|
||||
*/
|
||||
var hasActivateButton = function(element) {
|
||||
return getActivateButton(element).length ? true : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the element that contains the capabilities approval for
|
||||
* the user.
|
||||
*
|
||||
* @method getCapabilitiesContainer
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return bool
|
||||
*/
|
||||
var getCapabilitiesContainer = function(element) {
|
||||
return element.find(SELECTORS.CAPABILITIES_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the tool type has capabilities that need approval. If it
|
||||
* does then the container will be present.
|
||||
*
|
||||
* @method hasCapabilitiesContainer
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return bool
|
||||
*/
|
||||
var hasCapabilitiesContainer = function(element) {
|
||||
return getCapabilitiesContainer(element).length ? true : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the type id.
|
||||
*
|
||||
* @method getTypeId
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return string Type ID
|
||||
*/
|
||||
var getTypeId = function(element) {
|
||||
return element.attr('data-type-id');
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop any announcement currently visible on the card.
|
||||
*
|
||||
* @method clearAllAnnouncements
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var clearAllAnnouncements = function(element) {
|
||||
element.removeClass('announcement loading success fail capabilities');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the loading announcement.
|
||||
*
|
||||
* @method startLoading
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var startLoading = function(element) {
|
||||
clearAllAnnouncements(element);
|
||||
element.addClass('announcement loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the loading announcement.
|
||||
*
|
||||
* @method stopLoading
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var stopLoading = function(element) {
|
||||
element.removeClass('announcement loading');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the success announcement. The announcement is only
|
||||
* visible for 2 seconds.
|
||||
*
|
||||
* @method announceSuccess
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var announceSuccess = function(element) {
|
||||
var promise = $.Deferred();
|
||||
|
||||
clearAllAnnouncements(element);
|
||||
element.addClass('announcement success');
|
||||
setTimeout(function() {
|
||||
element.removeClass('announcement success');
|
||||
promise.resolve();
|
||||
}, ANNOUNCEMENT_TIMEOUT);
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the failure announcement. The announcement is only
|
||||
* visible for 2 seconds.
|
||||
*
|
||||
* @method announceFailure
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var announceFailure = function(element) {
|
||||
var promise = $.Deferred();
|
||||
|
||||
clearAllAnnouncements(element);
|
||||
element.addClass('announcement fail');
|
||||
setTimeout(function() {
|
||||
element.removeClass('announcement fail');
|
||||
promise.resolve();
|
||||
}, ANNOUNCEMENT_TIMEOUT);
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete the tool type from the Moodle server. Triggers a success
|
||||
* or failure announcement depending on the result.
|
||||
*
|
||||
* @method deleteType
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var deleteType = function(element) {
|
||||
var typeId = getTypeId(element);
|
||||
|
||||
if (typeId === "") {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
startLoading(element);
|
||||
var promise = toolType.delete(typeId);
|
||||
|
||||
promise.done(function() {
|
||||
stopLoading(element);
|
||||
announceSuccess(element).done(function() {
|
||||
element.remove();
|
||||
}).fail(notification.exception);
|
||||
});
|
||||
|
||||
promise.fail(function() { announceFailure(element); });
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save a given value in a data attribute on the element.
|
||||
*
|
||||
* @method setValueSnapshot
|
||||
* @private
|
||||
* @param object jQuery object representing the element.
|
||||
* @param string value to be saved.
|
||||
*/
|
||||
var setValueSnapshot = function(element, value) {
|
||||
element.attr('data-val-snapshot', value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the saved value from the element.
|
||||
*
|
||||
* @method getValueSnapshot
|
||||
* @private
|
||||
* @param object jQuery object representing the element.
|
||||
* @return string the saved value.
|
||||
*/
|
||||
var getValueSnapshot = function(element) {
|
||||
return element.attr('data-val-snapshot');
|
||||
};
|
||||
|
||||
/**
|
||||
* Save the current value of the tool description.
|
||||
*
|
||||
* @method snapshotDescription
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var snapshotDescription = function(element) {
|
||||
var descriptionElement = getDescriptionElement(element);
|
||||
|
||||
if (descriptionElement.hasClass('loading')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var description = descriptionElement.text().trim();
|
||||
setValueSnapshot(descriptionElement, description);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a request to update the description value for this tool
|
||||
* in the Moodle server.
|
||||
*
|
||||
* @method updateDescription
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var updateDescription = function(element) {
|
||||
var typeId = getTypeId(element);
|
||||
|
||||
// Return early if we don't have an id because it's
|
||||
// required to save the changes.
|
||||
if (typeId === "") {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
var descriptionElement = getDescriptionElement(element);
|
||||
|
||||
// Return early if we're already saving a value.
|
||||
if (descriptionElement.hasClass('loading')) {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
var description = descriptionElement.text().trim();
|
||||
var snapshotVal = getValueSnapshot(descriptionElement);
|
||||
|
||||
// If the value hasn't change then don't bother sending the
|
||||
// update request.
|
||||
if (snapshotVal == description) {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
descriptionElement.addClass('loading');
|
||||
|
||||
var promise = toolType.update({id: typeId, description: description});
|
||||
|
||||
promise.done(function(type) {
|
||||
descriptionElement.removeClass('loading');
|
||||
// Make sure the text is updated with the description from the
|
||||
// server, just in case the update didn't work.
|
||||
descriptionElement.text(type.description);
|
||||
}).fail(notification.exception);
|
||||
|
||||
// Probably need to handle failures better so that we can revert
|
||||
// the value in the input for the user.
|
||||
promise.fail(function() { descriptionElement.removeClass('loading'); });
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save the current value of the tool name.
|
||||
*
|
||||
* @method snapshotName
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var snapshotName = function(element) {
|
||||
var nameElement = getNameElement(element);
|
||||
|
||||
if (nameElement.hasClass('loading')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var name = nameElement.text().trim();
|
||||
setValueSnapshot(nameElement, name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a request to update the name value for this tool
|
||||
* in the Moodle server.
|
||||
*
|
||||
* @method updateName
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var updateName = function(element) {
|
||||
var typeId = getTypeId(element);
|
||||
|
||||
// Return if we don't have an id.
|
||||
if (typeId === "") {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
var nameElement = getNameElement(element);
|
||||
|
||||
// Return if we're already saving.
|
||||
if (nameElement.hasClass('loading')) {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
var name = nameElement.text().trim();
|
||||
var snapshotVal = getValueSnapshot(nameElement);
|
||||
|
||||
// If the value hasn't change then don't bother sending the
|
||||
// update request.
|
||||
if (snapshotVal == name) {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
nameElement.addClass('loading');
|
||||
var promise = toolType.update({id: typeId, name: name});
|
||||
|
||||
promise.done(function(type) {
|
||||
nameElement.removeClass('loading');
|
||||
// Make sure the text is updated with the name from the
|
||||
// server, just in case the update didn't work.
|
||||
nameElement.text(type.name);
|
||||
});
|
||||
|
||||
// Probably need to handle failures better so that we can revert
|
||||
// the value in the input for the user.
|
||||
promise.fail(function() { nameElement.removeClass('loading'); });
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a request to update the state for this tool to be configured (active)
|
||||
* in the Moodle server. A success or failure announcement is triggered depending
|
||||
* on the result.
|
||||
*
|
||||
* @method setStatusActive
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
* @return object jQuery Deferred object
|
||||
*/
|
||||
var setStatusActive = function(element) {
|
||||
var id = getTypeId(element);
|
||||
|
||||
// Return if we don't have an id.
|
||||
if (id === "") {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
startLoading(element);
|
||||
|
||||
var promise = toolType.update({
|
||||
id: id,
|
||||
state: toolType.constants.state.configured
|
||||
});
|
||||
|
||||
promise.done(function(toolTypeData) {
|
||||
stopLoading(element);
|
||||
|
||||
var announcePromise = announceSuccess(element);
|
||||
var renderPromise = templates.render('mod_lti/tool_card', toolTypeData);
|
||||
|
||||
$.when(renderPromise, announcePromise).then(function(renderResult) {
|
||||
var html = renderResult[0];
|
||||
var js = renderResult[1];
|
||||
|
||||
templates.replaceNode(element, html, js);
|
||||
});
|
||||
});
|
||||
|
||||
promise.fail(function() {
|
||||
stopLoading(element);
|
||||
announceFailure(element);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the capabilities approval screen to show which groups of data this
|
||||
* type requires access to in Moodle (if any).
|
||||
*
|
||||
* @method displayCapabilitiesApproval
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var displayCapabilitiesApproval = function(element) {
|
||||
element.addClass('announcement capabilities');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the capabilities approval screen.
|
||||
*
|
||||
* @method hideCapabilitiesApproval
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var hideCapabilitiesApproval = function(element) {
|
||||
element.removeClass('announcement capabilities');
|
||||
};
|
||||
|
||||
/**
|
||||
* The user wishes to activate this tool so show them the capabilities that
|
||||
* they need to agree to or if there are none then set the tool type's state
|
||||
* to active.
|
||||
*
|
||||
* @method activateToolType
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var activateToolType = function(element) {
|
||||
if (hasCapabilitiesContainer(element)) {
|
||||
displayCapabilitiesApproval(element);
|
||||
} else {
|
||||
setStatusActive(element);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up the listeners for user interaction on this tool type card.
|
||||
*
|
||||
* @method registerEventListeners
|
||||
* @private
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
var registerEventListeners = function(element) {
|
||||
var deleteButton = getDeleteButton(element);
|
||||
deleteButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
deleteType(element);
|
||||
});
|
||||
deleteButton.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
deleteButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var descriptionElement = getDescriptionElement(element);
|
||||
descriptionElement.focus(function(e) {
|
||||
e.preventDefault();
|
||||
// Save a copy of the current value for the description so that
|
||||
// we can check if the user has changed it before sending a request to
|
||||
// the server.
|
||||
snapshotDescription(element);
|
||||
});
|
||||
descriptionElement.blur(function(e) {
|
||||
e.preventDefault();
|
||||
updateDescription(element);
|
||||
});
|
||||
descriptionElement.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER) {
|
||||
e.preventDefault();
|
||||
descriptionElement.blur();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var nameElement = getNameElement(element);
|
||||
nameElement.focus(function(e) {
|
||||
e.preventDefault();
|
||||
// Save a copy of the current value for the name so that
|
||||
// we can check if the user has changed it before sending a request to
|
||||
// the server.
|
||||
snapshotName(element);
|
||||
});
|
||||
nameElement.blur(function(e) {
|
||||
e.preventDefault();
|
||||
updateName(element);
|
||||
});
|
||||
nameElement.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER) {
|
||||
e.preventDefault();
|
||||
nameElement.blur();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Only pending tool type cards have an activate button.
|
||||
if (hasActivateButton(element)) {
|
||||
var activateButton = getActivateButton(element);
|
||||
activateButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
activateToolType(element);
|
||||
});
|
||||
activateButton.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
activateButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (hasCapabilitiesContainer(element)) {
|
||||
var capabilitiesContainer = getCapabilitiesContainer(element);
|
||||
|
||||
capabilitiesContainer.on(ltiEvents.CAPABILITIES_AGREE, function() {
|
||||
setStatusActive(element);
|
||||
});
|
||||
|
||||
capabilitiesContainer.on(ltiEvents.CAPABILITIES_DECLINE, function() {
|
||||
hideCapabilitiesApproval(element);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return /** @alias module:mod_lti/tool_card_controller */ {
|
||||
|
||||
/**
|
||||
* Initialise this module.
|
||||
*
|
||||
* @param object jQuery object representing the tool card.
|
||||
*/
|
||||
init: function(element) {
|
||||
registerEventListeners(element);
|
||||
}
|
||||
};
|
||||
});
|
420
mod/lti/amd/src/tool_configure_controller.js
Normal file
420
mod/lti/amd/src/tool_configure_controller.js
Normal file
@ -0,0 +1,420 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Standard Ajax wrapper for Moodle. It calls the central Ajax script,
|
||||
* which can call any existing webservice using the current session.
|
||||
* In addition, it can batch multiple requests and return multiple responses.
|
||||
*
|
||||
* @module mod_lti/tool_configure_controller
|
||||
* @class tool_configure_controller
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['jquery', 'core/ajax', 'core/notification', 'core/templates', 'mod_lti/events', 'mod_lti/keys', 'mod_lti/tool_type'],
|
||||
function($, ajax, notification, templates, ltiEvents, KEYS, toolType) {
|
||||
|
||||
var SELECTORS = {
|
||||
REGISTRATION_FEEDBACK_CONTAINER: '#registration-feedback-container',
|
||||
EXTERNAL_REGISTRATION_CONTAINER: '#external-registration-container',
|
||||
EXTERNAL_REGISTRATION_PAGE_CONTAINER: '#external-registration-page-container',
|
||||
CARTRIDGE_REGISTRATION_CONTAINER: '#cartridge-registration-container',
|
||||
CARTRIDGE_REGISTRATION_FORM: '#cartridge-registration-form',
|
||||
ADD_TOOL_FORM: '#add-tool-form',
|
||||
TOOL_LIST_CONTAINER: '#tool-list-container',
|
||||
TOOL_CREATE_BUTTON: '#tool-create-button',
|
||||
REGISTRATION_CHOICE_CONTAINER: '#registration-choice-container',
|
||||
TOOL_URL: '#tool-url'
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the tool create button element.
|
||||
*
|
||||
* @method getToolCreateButton
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getToolCreateButton = function() {
|
||||
return $(SELECTORS.TOOL_CREATE_BUTTON);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the registration feedback container element.
|
||||
*
|
||||
* @method getRegistrationFeedbackContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getRegistrationFeedbackContainer = function() {
|
||||
return $(SELECTORS.REGISTRATION_FEEDBACK_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the tool list container element.
|
||||
*
|
||||
* @method getToolListContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getToolListContainer = function() {
|
||||
return $(SELECTORS.TOOL_LIST_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the external registration container element.
|
||||
*
|
||||
* @method getExternalRegistrationContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getExternalRegistrationContainer = function() {
|
||||
return $(SELECTORS.EXTERNAL_REGISTRATION_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the cartridge registration container element.
|
||||
*
|
||||
* @method getCartridgeRegistrationContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getCartridgeRegistrationContainer = function() {
|
||||
return $(SELECTORS.CARTRIDGE_REGISTRATION_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the registration choice container element.
|
||||
*
|
||||
* @method getRegistrationChoiceContainer
|
||||
* @private
|
||||
* @return object jQuery object
|
||||
*/
|
||||
var getRegistrationChoiceContainer = function() {
|
||||
return $(SELECTORS.REGISTRATION_CHOICE_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the tool type URL.
|
||||
*
|
||||
* @method getToolURL
|
||||
* @private
|
||||
* @return string
|
||||
*/
|
||||
var getToolURL = function() {
|
||||
return $(SELECTORS.TOOL_URL).val();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the external registration container.
|
||||
*
|
||||
* @method hideExternalRegistration
|
||||
* @private
|
||||
*/
|
||||
var hideExternalRegistration = function() {
|
||||
getExternalRegistrationContainer().addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the cartridge registration container.
|
||||
*
|
||||
* @method hideCartridgeRegistration
|
||||
* @private
|
||||
*/
|
||||
var hideCartridgeRegistration = function() {
|
||||
getCartridgeRegistrationContainer().addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the registration choice container.
|
||||
*
|
||||
* @method hideRegistrationChoices
|
||||
* @private
|
||||
*/
|
||||
var hideRegistrationChoices = function() {
|
||||
getRegistrationChoiceContainer().addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Display the external registration panel and hides the other
|
||||
* panels.
|
||||
*
|
||||
* @method showExternalRegistration
|
||||
* @private
|
||||
*/
|
||||
var showExternalRegistration = function(url) {
|
||||
hideCartridgeRegistration();
|
||||
hideRegistrationChoices();
|
||||
getExternalRegistrationContainer().removeClass('hidden');
|
||||
getExternalRegistrationContainer().find(SELECTORS.EXTERNAL_REGISTRATION_PAGE_CONTAINER).attr('data-registration-url', url);
|
||||
screenReaderAnnounce(getExternalRegistrationContainer());
|
||||
};
|
||||
|
||||
/**
|
||||
* Display the cartridge registration panel and hides the other
|
||||
* panels.
|
||||
*
|
||||
* @method showCartridgeRegistration
|
||||
* @private
|
||||
*/
|
||||
var showCartridgeRegistration = function(url) {
|
||||
hideExternalRegistration();
|
||||
hideRegistrationChoices();
|
||||
getCartridgeRegistrationContainer().removeClass('hidden');
|
||||
getCartridgeRegistrationContainer().find(SELECTORS.CARTRIDGE_REGISTRATION_FORM).attr('data-cartridge-url', url);
|
||||
screenReaderAnnounce(getCartridgeRegistrationContainer());
|
||||
};
|
||||
|
||||
/**
|
||||
* JAWS does not notice visibility changes with aria-live.
|
||||
* Remove and add the content back to force it to read it out.
|
||||
* This function can be removed once JAWS supports visibility.
|
||||
*
|
||||
* @method screenReaderAnnounce
|
||||
* @private
|
||||
*/
|
||||
var screenReaderAnnounce = function(element) {
|
||||
var childClones = element.children().clone(true, true);
|
||||
element.empty();
|
||||
element.append(childClones);
|
||||
};
|
||||
|
||||
/**
|
||||
* Display the registration choices panel and hides the other
|
||||
* panels.
|
||||
*
|
||||
* @method showRegistrationChoices
|
||||
* @private
|
||||
*/
|
||||
var showRegistrationChoices = function() {
|
||||
if (isRegistrationFeedbackVisible()) {
|
||||
// If the registration feedback is visible then we don't need
|
||||
// to do anything because it will display this content when it's
|
||||
// closed.
|
||||
return;
|
||||
}
|
||||
|
||||
hideExternalRegistration();
|
||||
hideCartridgeRegistration();
|
||||
getRegistrationChoiceContainer().removeClass('hidden');
|
||||
screenReaderAnnounce(getRegistrationChoiceContainer());
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the list of tool types.
|
||||
*
|
||||
* @method hideToolList
|
||||
* @private
|
||||
*/
|
||||
var hideToolList = function() {
|
||||
getToolListContainer().addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Display the list of tool types.
|
||||
*
|
||||
* @method hideToolList
|
||||
* @private
|
||||
*/
|
||||
var showToolList = function() {
|
||||
getToolListContainer().removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the registration feedback is being displayed.
|
||||
*
|
||||
* @method isRegistrationFeedbackVisible
|
||||
* @private
|
||||
* @return bool
|
||||
*/
|
||||
var isRegistrationFeedbackVisible = function() {
|
||||
return $.trim(getRegistrationFeedbackContainer().html());
|
||||
};
|
||||
|
||||
/**
|
||||
* Display the registration feedback alert and hide the other panels.
|
||||
*
|
||||
* @method showRegistrationFeedback
|
||||
* @private
|
||||
*/
|
||||
var showRegistrationFeedback = function(data) {
|
||||
templates.render('mod_lti/registration_feedback', data).done(function(html) {
|
||||
hideExternalRegistration();
|
||||
hideCartridgeRegistration();
|
||||
hideRegistrationChoices();
|
||||
|
||||
var container = getRegistrationFeedbackContainer();
|
||||
container.append(html);
|
||||
}).fail(notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the registration feedback alert and restore the choices panel.
|
||||
*
|
||||
* @method showRegistrationFeedback
|
||||
* @private
|
||||
*/
|
||||
var clearRegistrationFeedback = function() {
|
||||
var container = getRegistrationFeedbackContainer();
|
||||
container.empty();
|
||||
|
||||
showRegistrationChoices();
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the loading animation
|
||||
*
|
||||
* @method startLoading
|
||||
* @private
|
||||
* @param object jQuery object
|
||||
*/
|
||||
var startLoading = function(element) {
|
||||
element.addClass("loading");
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the loading animation
|
||||
*
|
||||
* @method stopLoading
|
||||
* @private
|
||||
* @param object jQuery object
|
||||
*/
|
||||
var stopLoading = function(element) {
|
||||
element.removeClass("loading");
|
||||
};
|
||||
|
||||
/**
|
||||
* Refresh the list of tool types and render the new ones.
|
||||
*
|
||||
* @method reloadToolList
|
||||
* @private
|
||||
*/
|
||||
var reloadToolList = function() {
|
||||
var container = getToolListContainer();
|
||||
startLoading(container);
|
||||
|
||||
toolType.query().done(function(types) {
|
||||
templates.render('mod_lti/tool_list', {tools: types}).done(function(html, js) {
|
||||
container.empty();
|
||||
container.append(html);
|
||||
templates.runTemplateJS(js);
|
||||
}).fail(notification.exception);
|
||||
}).fail(notification.exception).always(function() { stopLoading(container); });
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger appropriate registration process process for the user input
|
||||
* URL. It can either be a cartridge or a registration url.
|
||||
*
|
||||
* @method addTool
|
||||
* @private
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
var addTool = function() {
|
||||
var url = getToolURL();
|
||||
|
||||
if (url === "") {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
|
||||
var toolButton = getToolCreateButton();
|
||||
startLoading(toolButton);
|
||||
|
||||
var promise = toolType.isCartridge(url);
|
||||
|
||||
promise.always(function() { stopLoading(toolButton); });
|
||||
|
||||
promise.done(function(result) {
|
||||
if (result.iscartridge) {
|
||||
$(SELECTORS.TOOL_URL).val('');
|
||||
$(document).trigger(ltiEvents.START_CARTRIDGE_REGISTRATION, url);
|
||||
} else {
|
||||
showExternalRegistration(url);
|
||||
$(SELECTORS.TOOL_URL).val('');
|
||||
$(document).trigger(ltiEvents.START_EXTERNAL_REGISTRATION);
|
||||
hideToolList();
|
||||
}
|
||||
});
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up the listeners for user interaction on the page.
|
||||
*
|
||||
* @method registerEventListeners
|
||||
* @private
|
||||
*/
|
||||
var registerEventListeners = function() {
|
||||
|
||||
// These are events fired by the registration processes. Either
|
||||
// the cartridge registration or the external registration url.
|
||||
$(document).on(ltiEvents.NEW_TOOL_TYPE, function() {
|
||||
reloadToolList();
|
||||
});
|
||||
|
||||
$(document).on(ltiEvents.STOP_EXTERNAL_REGISTRATION, function() {
|
||||
showToolList();
|
||||
showRegistrationChoices();
|
||||
});
|
||||
|
||||
$(document).on(ltiEvents.START_CARTRIDGE_REGISTRATION, function(event, url) {
|
||||
showCartridgeRegistration(url);
|
||||
});
|
||||
|
||||
$(document).on(ltiEvents.STOP_CARTRIDGE_REGISTRATION, function() {
|
||||
getCartridgeRegistrationContainer().find(SELECTORS.CARTRIDGE_REGISTRATION_FORM).removeAttr('data-cartridge-url');
|
||||
showRegistrationChoices();
|
||||
});
|
||||
|
||||
$(document).on(ltiEvents.REGISTRATION_FEEDBACK, function(event, data) {
|
||||
showRegistrationFeedback(data);
|
||||
});
|
||||
|
||||
var form = $(SELECTORS.ADD_TOOL_FORM);
|
||||
form.submit(function(e) {
|
||||
e.preventDefault();
|
||||
addTool();
|
||||
});
|
||||
|
||||
var feedbackContainer = getRegistrationFeedbackContainer();
|
||||
feedbackContainer.click(function(e) {
|
||||
e.preventDefault();
|
||||
clearRegistrationFeedback();
|
||||
});
|
||||
feedbackContainer.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
clearRegistrationFeedback();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return /** @alias module:mod_lti/cartridge_registration_form */ {
|
||||
|
||||
/**
|
||||
* Initialise this module.
|
||||
*/
|
||||
init: function() {
|
||||
registerEventListeners();
|
||||
reloadToolList();
|
||||
}
|
||||
};
|
||||
});
|
74
mod/lti/amd/src/tool_proxy.js
Normal file
74
mod/lti/amd/src/tool_proxy.js
Normal file
@ -0,0 +1,74 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Provides an interface for a tool proxy in the Moodle server.
|
||||
*
|
||||
* @module mod_lti/tool_proxy
|
||||
* @class tool_proxy
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['core/ajax', 'core/notification'], function(ajax, notification) {
|
||||
return /** @alias module:mod_lti/tool_proxy */ {
|
||||
/**
|
||||
* Delete a tool proxy from Moodle.
|
||||
*
|
||||
* @method delete
|
||||
* @public
|
||||
* @param int Tool proxy ID
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
delete: function(id) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_delete_tool_proxy',
|
||||
args: {
|
||||
id: id
|
||||
}
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a tool proxy in Moodle.
|
||||
*
|
||||
* See mod/lti/classes/external.php create_tool_proxy_parameters
|
||||
*
|
||||
* @method create
|
||||
* @public
|
||||
* @param object Tool proxy properties
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
create: function(args) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_create_tool_proxy',
|
||||
args: args
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
}
|
||||
};
|
||||
});
|
171
mod/lti/amd/src/tool_type.js
Normal file
171
mod/lti/amd/src/tool_type.js
Normal file
@ -0,0 +1,171 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Provides an interface for a tool type in the Moodle server.
|
||||
*
|
||||
* @module mod_lti/tool_type
|
||||
* @class tool_type
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since 3.1
|
||||
*/
|
||||
define(['core/ajax', 'core/notification'], function(ajax, notification) {
|
||||
return /** @alias module:mod_lti/tool_type */ {
|
||||
/**
|
||||
* Get a list of tool types from Moodle for the given
|
||||
* search args.
|
||||
*
|
||||
* See also:
|
||||
* mod/lti/classes/external.php get_tool_types_parameters()
|
||||
*
|
||||
* @method query
|
||||
* @public
|
||||
* @param object Search parameters
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
query: function(args) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_get_tool_types',
|
||||
args: args || {}
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a tool type in Moodle.
|
||||
*
|
||||
* See also:
|
||||
* mod/lti/classes/external.php create_tool_type_parameters()
|
||||
*
|
||||
* @method create
|
||||
* @public
|
||||
* @param object Tool type properties
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
create: function(args) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_create_tool_type',
|
||||
args: args
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update a tool type in Moodle.
|
||||
*
|
||||
* See also:
|
||||
* mod/lti/classes/external.php update_tool_type_parameters()
|
||||
*
|
||||
* @method update
|
||||
* @public
|
||||
* @param object Tool type properties
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
update: function(args) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_update_tool_type',
|
||||
args: args
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete a tool type from Moodle.
|
||||
*
|
||||
* @method delete
|
||||
* @public
|
||||
* @param int Tool type ID
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
delete: function(id) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_delete_tool_type',
|
||||
args: {
|
||||
id: id
|
||||
}
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a list of tool types from Moodle for the given
|
||||
* tool proxy id.
|
||||
*
|
||||
* @method query
|
||||
* @public
|
||||
* @param int Tool proxty id
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
getFromToolProxyId: function(id) {
|
||||
return this.query({toolproxyid: id});
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the given URL is a cartridge URL.
|
||||
*
|
||||
* @method isCartridge
|
||||
* @public
|
||||
* @param string URL
|
||||
* @return object jQuery deferred object
|
||||
*/
|
||||
isCartridge: function(url) {
|
||||
var request = {
|
||||
methodname: 'mod_lti_is_cartridge',
|
||||
args: {
|
||||
url: url
|
||||
}
|
||||
};
|
||||
|
||||
var promise = ajax.call([request])[0];
|
||||
|
||||
promise.fail(notification.exception);
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tool type constants.
|
||||
*/
|
||||
constants: {
|
||||
state: {
|
||||
configured: 1,
|
||||
pending: 2,
|
||||
rejected: 3
|
||||
},
|
||||
}
|
||||
};
|
||||
});
|
@ -41,6 +41,74 @@ require_once($CFG->dirroot . '/mod/lti/locallib.php');
|
||||
*/
|
||||
class mod_lti_external extends external_api {
|
||||
|
||||
/**
|
||||
* Returns description of a tool type
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
private static function get_tool_type_return_parameters() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool type id'),
|
||||
'name' => new external_value(PARAM_TEXT, 'Tool type name'),
|
||||
'description' => new external_value(PARAM_TEXT, 'Tool type description'),
|
||||
'urls' => new external_single_structure(
|
||||
array(
|
||||
'icon' => new external_value(PARAM_URL, 'Tool type icon URL'),
|
||||
'edit' => new external_value(PARAM_URL, 'Tool type edit URL'),
|
||||
'course' => new external_value(PARAM_URL, 'Tool type edit URL', VALUE_OPTIONAL),
|
||||
)
|
||||
),
|
||||
'state' => new external_single_structure(
|
||||
array(
|
||||
'text' => new external_value(PARAM_TEXT, 'Tool type state name string'),
|
||||
'pending' => new external_value(PARAM_BOOL, 'Is the state pending'),
|
||||
'configured' => new external_value(PARAM_BOOL, 'Is the state configured'),
|
||||
'rejected' => new external_value(PARAM_BOOL, 'Is the state rejected'),
|
||||
'unknown' => new external_value(PARAM_BOOL, 'Is the state unknown'),
|
||||
)
|
||||
),
|
||||
'hascapabilitygroups' => new external_value(PARAM_BOOL, 'Indicate if capabilitygroups is populated'),
|
||||
'capabilitygroups' => new external_multiple_structure(
|
||||
new external_value(PARAM_TEXT, 'Tool type capability groups enabled'),
|
||||
'Array of capability groups', VALUE_DEFAULT, array()
|
||||
),
|
||||
'courseid' => new external_value(PARAM_INT, 'Tool type course', VALUE_DEFAULT, 0),
|
||||
'instanceids' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'LTI instance ID'),
|
||||
'IDs for the LTI instances using this type', VALUE_DEFAULT, array()
|
||||
),
|
||||
'instancecount' => new external_value(PARAM_INT, 'The number of times this tool is being used')
|
||||
), 'Tool'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of a tool proxy
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
private static function get_tool_proxy_return_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool proxy id'),
|
||||
'name' => new external_value(PARAM_TEXT, 'Tool proxy name'),
|
||||
'regurl' => new external_value(PARAM_URL, 'Tool proxy registration URL'),
|
||||
'state' => new external_value(PARAM_INT, 'Tool proxy state'),
|
||||
'guid' => new external_value(PARAM_TEXT, 'Tool proxy globally unique identifier'),
|
||||
'secret' => new external_value(PARAM_TEXT, 'Tool proxy shared secret'),
|
||||
'vendorcode' => new external_value(PARAM_TEXT, 'Tool proxy consumer code'),
|
||||
'capabilityoffered' => new external_value(PARAM_TEXT, 'Tool proxy capabilities offered'),
|
||||
'serviceoffered' => new external_value(PARAM_TEXT, 'Tool proxy services offered'),
|
||||
'toolproxy' => new external_value(PARAM_TEXT, 'Tool proxy'),
|
||||
'timecreated' => new external_value(PARAM_INT, 'Tool proxy time created'),
|
||||
'timemodified' => new external_value(PARAM_INT, 'Tool proxy modified'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
@ -336,4 +404,546 @@ class mod_lti_external extends external_api {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function create_tool_proxy_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'name' => new external_value(PARAM_TEXT, 'Tool proxy name', VALUE_DEFAULT, ''),
|
||||
'regurl' => new external_value(PARAM_URL, 'Tool proxy registration URL'),
|
||||
'capabilityoffered' => new external_multiple_structure(
|
||||
new external_value(PARAM_TEXT, 'Tool proxy capabilities offered'),
|
||||
'Array of capabilities', VALUE_DEFAULT, array()
|
||||
),
|
||||
'serviceoffered' => new external_multiple_structure(
|
||||
new external_value(PARAM_TEXT, 'Tool proxy services offered'),
|
||||
'Array of services', VALUE_DEFAULT, array()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new tool proxy
|
||||
*
|
||||
* @param string $name Tool proxy name
|
||||
* @param string $registrationurl Registration url
|
||||
* @param string[] $capabilityoffered List of capabilities this tool proxy should be offered
|
||||
* @param string[] $serviceoffered List of services this tool proxy should be offered
|
||||
* @return object The new tool proxy
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function create_tool_proxy($name, $registrationurl, $capabilityoffered, $serviceoffered) {
|
||||
$params = self::validate_parameters(self::create_tool_proxy_parameters(),
|
||||
array(
|
||||
'name' => $name,
|
||||
'regurl' => $registrationurl,
|
||||
'capabilityoffered' => $capabilityoffered,
|
||||
'serviceoffered' => $serviceoffered
|
||||
));
|
||||
$name = $params['name'];
|
||||
$regurl = $params['regurl'];
|
||||
$capabilityoffered = $params['capabilityoffered'];
|
||||
$serviceoffered = $params['serviceoffered'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
// Can't create duplicate proxies with the same URL.
|
||||
$duplicates = lti_get_tool_proxies_from_registration_url($registrationurl);
|
||||
if (!empty($duplicates)) {
|
||||
throw new moodle_exception('duplicateregurl', 'mod_lti');
|
||||
}
|
||||
|
||||
$config = new stdClass();
|
||||
$config->lti_registrationurl = $registrationurl;
|
||||
|
||||
if (!empty($name)) {
|
||||
$config->lti_registrationname = $name;
|
||||
}
|
||||
|
||||
if (!empty($capabilityoffered)) {
|
||||
$config->lti_capabilities = $capabilitiesoffered;
|
||||
}
|
||||
|
||||
if (!empty($serviceoffered)) {
|
||||
$config->lti_services = $serviceoffered;
|
||||
}
|
||||
|
||||
$id = lti_add_tool_proxy($config);
|
||||
$toolproxy = lti_get_tool_proxy($id);
|
||||
|
||||
// Pending makes more sense than configured as the first state, since
|
||||
// the next step is to register, which requires the state be pending.
|
||||
$toolproxy->state = LTI_TOOL_PROXY_STATE_PENDING;
|
||||
lti_update_tool_proxy($toolproxy);
|
||||
|
||||
return $toolproxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function create_tool_proxy_returns() {
|
||||
return self::get_tool_proxy_return_parameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function delete_tool_proxy_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool proxy id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the course module viewed event and update the module completion status.
|
||||
*
|
||||
* @param int $id the lti instance id
|
||||
* @return object The tool proxy
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function delete_tool_proxy($id) {
|
||||
$params = self::validate_parameters(self::delete_tool_proxy_parameters(),
|
||||
array(
|
||||
'id' => $id,
|
||||
));
|
||||
$id = $params['id'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
$toolproxy = lti_get_tool_proxy($id);
|
||||
|
||||
lti_delete_tool_proxy($id);
|
||||
|
||||
return $toolproxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function delete_tool_proxy_returns() {
|
||||
return self::get_tool_proxy_return_parameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.0
|
||||
*/
|
||||
public static function get_tool_proxy_registration_request_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool proxy id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registration request for a tool proxy.
|
||||
*
|
||||
* @param int $id the lti instance id
|
||||
* @return array of registration parameters
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function get_tool_proxy_registration_request($id) {
|
||||
$params = self::validate_parameters(self::get_tool_proxy_registration_request_parameters(),
|
||||
array(
|
||||
'id' => $id,
|
||||
));
|
||||
$id = $params['id'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
$toolproxy = lti_get_tool_proxy($id);
|
||||
return lti_build_registration_request($toolproxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_tool_proxy_registration_request_returns() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'lti_message_type' => new external_value(PARAM_ALPHANUMEXT, 'LTI message type'),
|
||||
'lti_version' => new external_value(PARAM_ALPHANUMEXT, 'LTI version'),
|
||||
'reg_key' => new external_value(PARAM_TEXT, 'Tool proxy registration key'),
|
||||
'reg_password' => new external_value(PARAM_TEXT, 'Tool proxy registration password'),
|
||||
'tc_profile_url' => new external_value(PARAM_URL, 'Tool consumers profile URL'),
|
||||
'launch_presentation_return_url' => new external_value(PARAM_URL, 'URL to redirect on registration completion'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_tool_types_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'toolproxyid' => new external_value(PARAM_INT, 'Tool proxy id', VALUE_DEFAULT, 0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tool types.
|
||||
*
|
||||
* @param int $toolproxyid The tool proxy id
|
||||
* @return array of tool types
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function get_tool_types($toolproxyid) {
|
||||
global $PAGE;
|
||||
$params = self::validate_parameters(self::get_tool_types_parameters(),
|
||||
array(
|
||||
'toolproxyid' => $toolproxyid
|
||||
));
|
||||
$toolproxyid = $params['toolproxyid'];
|
||||
|
||||
$types = array();
|
||||
$context = context_system::instance();
|
||||
|
||||
self::validate_context($context);
|
||||
$PAGE->set_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
if (!empty($toolproxyid)) {
|
||||
$types = lti_get_lti_types_from_proxy_id($toolproxyid);
|
||||
} else {
|
||||
$types = lti_get_lti_types();
|
||||
}
|
||||
|
||||
return array_map("serialise_tool_type", array_values($types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function get_tool_types_returns() {
|
||||
return new external_multiple_structure(
|
||||
self::get_tool_type_return_parameters()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function create_tool_type_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'cartridgeurl' => new external_value(PARAM_URL, 'URL to cardridge to load tool information', VALUE_DEFAULT, ''),
|
||||
'key' => new external_value(PARAM_TEXT, 'Consumer key', VALUE_DEFAULT, ''),
|
||||
'secret' => new external_value(PARAM_TEXT, 'Shared secret', VALUE_DEFAULT, ''),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tool type.
|
||||
*
|
||||
* @param string $cartridgeurl Url of the xml cartridge representing the LTI tool
|
||||
* @param string $key The consumer key to identify this consumer
|
||||
* @param string $secret The secret
|
||||
* @return array created tool type
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception If the tool type could not be created
|
||||
*/
|
||||
public static function create_tool_type($cartridgeurl, $key, $secret) {
|
||||
$params = self::validate_parameters(self::create_tool_type_parameters(),
|
||||
array(
|
||||
'cartridgeurl' => $cartridgeurl,
|
||||
'key' => $key,
|
||||
'secret' => $secret
|
||||
));
|
||||
$cartridgeurl = $params['cartridgeurl'];
|
||||
$key = $params['key'];
|
||||
$secret = $params['secret'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
$id = null;
|
||||
|
||||
if (!empty($cartridgeurl)) {
|
||||
$type = new stdClass();
|
||||
$data = new stdClass();
|
||||
$type->state = LTI_TOOL_STATE_CONFIGURED;
|
||||
$data->lti_coursevisible = 1;
|
||||
$data->lti_sendname = LTI_SETTING_DELEGATE;
|
||||
$data->lti_sendemailaddr = LTI_SETTING_DELEGATE;
|
||||
$data->lti_acceptgrades = LTI_SETTING_DELEGATE;
|
||||
$data->lti_forcessl = 0;
|
||||
|
||||
if (!empty($key)) {
|
||||
$data->lti_resourcekey = $key;
|
||||
}
|
||||
|
||||
if (!empty($secret)) {
|
||||
$data->lti_password = $secret;
|
||||
}
|
||||
|
||||
lti_load_type_from_cartridge($cartridgeurl, $data);
|
||||
if (empty($data->lti_toolurl)) {
|
||||
throw new moodle_exception('unabletocreatetooltype', 'mod_lti');
|
||||
} else {
|
||||
$id = lti_add_type($type, $data);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
$type = lti_get_type($id);
|
||||
return serialise_tool_type($type);
|
||||
} else {
|
||||
throw new moodle_exception('unabletocreatetooltype', 'mod_lti');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function create_tool_type_returns() {
|
||||
return self::get_tool_type_return_parameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function update_tool_type_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool type id'),
|
||||
'name' => new external_value(PARAM_TEXT, 'Tool type name', VALUE_DEFAULT, null),
|
||||
'description' => new external_value(PARAM_TEXT, 'Tool type description', VALUE_DEFAULT, null),
|
||||
'state' => new external_value(PARAM_INT, 'Tool type state', VALUE_DEFAULT, null)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a tool type.
|
||||
*
|
||||
* @param int $id The id of the tool type to update
|
||||
* @param string $name The name of the tool type
|
||||
* @param string $description The name of the tool type
|
||||
* @param int $state The state of the tool type
|
||||
* @return array updated tool type
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function update_tool_type($id, $name, $description, $state) {
|
||||
$params = self::validate_parameters(self::update_tool_type_parameters(),
|
||||
array(
|
||||
'id' => $id,
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'state' => $state,
|
||||
));
|
||||
$id = $params['id'];
|
||||
$name = $params['name'];
|
||||
$description = $params['description'];
|
||||
$state = $params['state'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
$type = lti_get_type($id);
|
||||
|
||||
if (empty($type)) {
|
||||
throw new moodle_exception('unabletofindtooltype', 'mod_lti', '', array('id' => $id));
|
||||
}
|
||||
|
||||
if (!empty($name)) {
|
||||
$type->name = $name;
|
||||
}
|
||||
|
||||
if (!empty($description)) {
|
||||
$type->description = $description;
|
||||
}
|
||||
|
||||
if (!empty($state)) {
|
||||
// Valid state range.
|
||||
if (in_array($state, array(1, 2, 3))) {
|
||||
$type->state = $state;
|
||||
} else {
|
||||
throw new moodle_exception("Invalid state: $state - must be 1, 2, or 3");
|
||||
}
|
||||
}
|
||||
|
||||
lti_update_type($type, new stdClass());
|
||||
|
||||
return serialise_tool_type($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function update_tool_type_returns() {
|
||||
return self::get_tool_type_return_parameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function delete_tool_type_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool type id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a tool type.
|
||||
*
|
||||
* @param int $id The id of the tool type to be deleted
|
||||
* @return array deleted tool type
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function delete_tool_type($id) {
|
||||
$params = self::validate_parameters(self::delete_tool_type_parameters(),
|
||||
array(
|
||||
'id' => $id,
|
||||
));
|
||||
$id = $params['id'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
$type = lti_get_type($id);
|
||||
|
||||
if (!empty($type)) {
|
||||
lti_delete_type($id);
|
||||
|
||||
// If this is the last type for this proxy then remove the proxy
|
||||
// as well so that it isn't orphaned.
|
||||
$types = lti_get_lti_types_from_proxy_id($type->toolproxyid);
|
||||
if (empty($types)) {
|
||||
lti_delete_tool_proxy($type->toolproxyid);
|
||||
}
|
||||
}
|
||||
|
||||
return array('id' => $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function delete_tool_type_returns() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Tool type id'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function is_cartridge_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'url' => new external_value(PARAM_URL, 'Tool url'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the url to a tool is for a cartridge.
|
||||
*
|
||||
* @param string $url Url that may or may not be an xml cartridge
|
||||
* @return bool True if the url is for a cartridge.
|
||||
* @since Moodle 3.1
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function is_cartridge($url) {
|
||||
$params = self::validate_parameters(self::is_cartridge_parameters(),
|
||||
array(
|
||||
'url' => $url,
|
||||
));
|
||||
$url = $params['url'];
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
require_capability('moodle/site:config', $context);
|
||||
|
||||
$iscartridge = lti_is_cartridge($url);
|
||||
|
||||
return array('iscartridge' => $iscartridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
public static function is_cartridge_returns() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'iscartridge' => new external_value(PARAM_BOOL, 'True if the URL is a cartridge'),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
50
mod/lti/classes/output/external_registration_return_page.php
Normal file
50
mod/lti/classes/output/external_registration_return_page.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class containing data for external registration return page.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lti\output;
|
||||
|
||||
require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
|
||||
use renderable;
|
||||
use templatable;
|
||||
use renderer_base;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class containing data for tool_configure page
|
||||
*
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class external_registration_return_page implements renderable, templatable {
|
||||
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
* @param renderer_base $output The renderer
|
||||
* @return stdClass Data to be used by the template
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
return new stdClass();
|
||||
}
|
||||
}
|
61
mod/lti/classes/output/renderer.php
Normal file
61
mod/lti/classes/output/renderer.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Renderer class for template library.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lti\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
use plugin_renderer_base;
|
||||
|
||||
/**
|
||||
* Renderer class for template library.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class renderer extends plugin_renderer_base {
|
||||
|
||||
/**
|
||||
* Defer to template.
|
||||
*
|
||||
* @param tool_configure_page $page
|
||||
*
|
||||
* @return string html for the page
|
||||
*/
|
||||
public function render_tool_configure_page($page) {
|
||||
$data = $page->export_for_template($this);
|
||||
return parent::render_from_template('mod_lti/tool_configure', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the external registration return page
|
||||
*
|
||||
* @param tool_configure_page $page
|
||||
*
|
||||
* @return string html for the page
|
||||
*/
|
||||
public function render_external_registration_return_page($page) {
|
||||
return '';
|
||||
}
|
||||
}
|
59
mod/lti/classes/output/tool_configure_page.php
Normal file
59
mod/lti/classes/output/tool_configure_page.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class containing data for tool_configure page
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lti\output;
|
||||
|
||||
require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
|
||||
use moodle_url;
|
||||
use renderable;
|
||||
use templatable;
|
||||
use renderer_base;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class containing data for tool_configure page
|
||||
*
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_configure_page implements renderable, templatable {
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
* @param renderer_base $output The renderer
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(renderer_base $output) {
|
||||
$data = new stdClass();
|
||||
|
||||
$url = new moodle_url('/mod/lti/typessettings.php', array('sesskey' => sesskey(), 'returnto' => 'toolconfigure'));
|
||||
$data->configuremanualurl = $url->out();
|
||||
$url = new moodle_url('/admin/settings.php?section=modsettinglti');
|
||||
$data->managetoolsurl = $url->out();
|
||||
$url = new moodle_url('/mod/lti/toolproxies.php');
|
||||
$data->managetoolproxiesurl = $url->out();
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/lti/db" VERSION="20140612" COMMENT="XMLDB file for Moodle mod/lti"
|
||||
<XMLDB PATH="mod/lti/db" VERSION="20151204" COMMENT="XMLDB file for Moodle mod/lti"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
@ -80,6 +80,7 @@
|
||||
<FIELD NAME="createdby" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="description" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="A description of what this LTI module is."/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
|
@ -53,4 +53,76 @@ $functions = array(
|
||||
'capabilities' => 'mod/lti:view',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
|
||||
),
|
||||
|
||||
'mod_lti_create_tool_proxy' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'create_tool_proxy',
|
||||
'description' => 'Create a tool proxy',
|
||||
'type' => 'write',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_delete_tool_proxy' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'delete_tool_proxy',
|
||||
'description' => 'Delete a tool proxy',
|
||||
'type' => 'write',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_get_tool_proxy_registration_request' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'get_tool_proxy_registration_request',
|
||||
'description' => 'Get a registration request for a tool proxy',
|
||||
'type' => 'read',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_get_tool_types' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'get_tool_types',
|
||||
'description' => 'Get a list of the tool types',
|
||||
'type' => 'read',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_create_tool_type' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'create_tool_type',
|
||||
'description' => 'Create a tool type',
|
||||
'type' => 'write',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_update_tool_type' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'update_tool_type',
|
||||
'description' => 'Update a tool type',
|
||||
'type' => 'write',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_delete_tool_type' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'delete_tool_type',
|
||||
'description' => 'Delete a tool type',
|
||||
'type' => 'write',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_is_cartridge' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'is_cartridge',
|
||||
'description' => 'Determine if the given url is for a cartridge',
|
||||
'type' => 'read',
|
||||
'capabilities' => 'mod/lti:manage',
|
||||
'ajax' => true
|
||||
),
|
||||
);
|
||||
|
@ -179,5 +179,20 @@ function xmldb_lti_upgrade($oldversion) {
|
||||
// Moodle v3.0.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
if ($oldversion < 2016041800) {
|
||||
|
||||
// Define field description to be added to lti_types.
|
||||
$table = new xmldb_table('lti_types');
|
||||
$field = new xmldb_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null, 'timemodified');
|
||||
|
||||
// Conditionally launch add field description.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Lti savepoint reached.
|
||||
upgrade_mod_savepoint(true, 2016041800, 'lti');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -69,8 +69,12 @@ class mod_lti_edit_types_form extends moodleform{
|
||||
$mform->addRule('lti_typename', null, 'required', null, 'client');
|
||||
|
||||
$mform->addElement('text', 'lti_toolurl', get_string('toolurl', 'lti'), array('size' => '64'));
|
||||
$mform->setType('lti_toolurl', PARAM_TEXT);
|
||||
$mform->setType('lti_toolurl', PARAM_URL);
|
||||
$mform->addHelpButton('lti_toolurl', 'toolurl', 'lti');
|
||||
|
||||
$mform->addElement('textarea', 'lti_description', get_string('tooldescription', 'lti'), array('rows' => 4, 'cols' => 60));
|
||||
$mform->setType('lti_description', PARAM_TEXT);
|
||||
$mform->addHelpButton('lti_description', 'tooldescription', 'lti');
|
||||
if (!$istool) {
|
||||
$mform->addRule('lti_toolurl', null, 'required', null, 'client');
|
||||
} else {
|
||||
@ -101,6 +105,7 @@ class mod_lti_edit_types_form extends moodleform{
|
||||
if (!$istool && !empty($this->_customdata->isadmin)) {
|
||||
$mform->addElement('checkbox', 'lti_coursevisible', ' ', ' ' . get_string('show_in_course', 'lti'));
|
||||
$mform->addHelpButton('lti_coursevisible', 'show_in_course', 'lti');
|
||||
$mform->setDefault('lti_coursevisible', '1');
|
||||
} else {
|
||||
$mform->addElement('hidden', 'lti_coursevisible', '1');
|
||||
}
|
||||
@ -184,7 +189,7 @@ class mod_lti_edit_types_form extends moodleform{
|
||||
$mform->addHelpButton('lti_organizationid', 'organizationid', 'lti');
|
||||
|
||||
$mform->addElement('text', 'lti_organizationurl', get_string('organizationurl', 'lti'));
|
||||
$mform->setType('lti_organizationurl', PARAM_TEXT);
|
||||
$mform->setType('lti_organizationurl', PARAM_URL);
|
||||
$mform->addHelpButton('lti_organizationurl', 'organizationurl', 'lti');
|
||||
}
|
||||
}
|
||||
|
48
mod/lti/externalregistrationreturn.php
Normal file
48
mod/lti/externalregistrationreturn.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?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 registering a tool proxy.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie
|
||||
* @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');
|
||||
|
||||
$status = optional_param('status', '', PARAM_TEXT);
|
||||
$msg = optional_param('lti_msg', '', PARAM_TEXT);
|
||||
$err = optional_param('lti_errormsg', '', PARAM_TEXT);
|
||||
$id = optional_param('id', 0, PARAM_INT);
|
||||
|
||||
// No guest autologin.
|
||||
require_sesskey();
|
||||
require_login(0, false);
|
||||
|
||||
$systemcontext = context_system::instance();
|
||||
require_capability('moodle/site:config', $systemcontext);
|
||||
|
||||
$pageurl = new moodle_url('/mod/lti/externalregistrationreturn.php');
|
||||
$PAGE->set_context($systemcontext);
|
||||
$PAGE->set_url($pageurl);
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
echo $OUTPUT->header();
|
||||
$params = array('message' => s($msg), 'error' => s($err), 'id' => $id, 'status' => s($status));
|
||||
$PAGE->requires->js_call_amd('mod_lti/external_registration_return', 'init', $params);
|
||||
echo $OUTPUT->footer();
|
@ -25,6 +25,7 @@
|
||||
|
||||
require_once('../../config.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/edit_form.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/lib.php');
|
||||
|
||||
$courseid = required_param('course', PARAM_INT);
|
||||
|
||||
@ -32,6 +33,7 @@ require_login($courseid, false);
|
||||
$url = new moodle_url('/mod/lti/instructor_edit_tool_type.php');
|
||||
$PAGE->set_url($url);
|
||||
$PAGE->set_pagelayout('popup');
|
||||
$PAGE->set_title(get_string('edittype', 'mod_lti'));
|
||||
|
||||
$action = optional_param('action', null, PARAM_TEXT);
|
||||
$typeid = optional_param('typeid', null, PARAM_INT);
|
||||
@ -48,83 +50,73 @@ if (!empty($typeid)) {
|
||||
}
|
||||
}
|
||||
|
||||
$form = new mod_lti_edit_types_form();
|
||||
if ($data = $form->get_data()) {
|
||||
$type = new stdClass();
|
||||
|
||||
if (!empty($typeid)) {
|
||||
$type->id = $typeid;
|
||||
$name = json_encode($data->lti_typename);
|
||||
|
||||
lti_update_type($type, $data);
|
||||
|
||||
$fromdb = lti_get_type($typeid);
|
||||
$json = json_encode($fromdb);
|
||||
|
||||
// Output script to update the calling window.
|
||||
$script = "
|
||||
<html>
|
||||
<script type=\"text/javascript\">
|
||||
window.opener.M.mod_lti.editor.updateToolType({$json});
|
||||
window.close();
|
||||
</script>
|
||||
</html>
|
||||
";
|
||||
|
||||
echo $script;
|
||||
die;
|
||||
} else {
|
||||
$type->state = LTI_TOOL_STATE_CONFIGURED;
|
||||
$type->course = $COURSE->id;
|
||||
|
||||
$id = lti_add_type($type, $data);
|
||||
|
||||
$fromdb = lti_get_type($id);
|
||||
$json = json_encode($fromdb);
|
||||
|
||||
// Output script to update the calling window.
|
||||
$script = "
|
||||
<html>
|
||||
<script type=\"text/javascript\">
|
||||
window.opener.M.mod_lti.editor.addToolType({$json});
|
||||
window.close();
|
||||
</script>
|
||||
</html>
|
||||
";
|
||||
|
||||
echo $script;
|
||||
|
||||
die;
|
||||
}
|
||||
} else if ($form->is_cancelled()) {
|
||||
$script = "
|
||||
<html>
|
||||
<script type=\"text/javascript\">
|
||||
window.close();
|
||||
</script>
|
||||
</html>
|
||||
";
|
||||
|
||||
echo $script;
|
||||
die;
|
||||
}
|
||||
|
||||
// Delete action is called via ajax.
|
||||
if ($action == 'delete') {
|
||||
lti_delete_type($typeid);
|
||||
die;
|
||||
}
|
||||
|
||||
// Add a timeout for closing for behat so it can check for errors before switching back to the main window.
|
||||
$timeout = 0;
|
||||
if (defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) {
|
||||
$timeout = 2000;
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading(get_string('toolsetup', 'lti'));
|
||||
$form = new mod_lti_edit_types_form();
|
||||
|
||||
if ($action == 'add') {
|
||||
$form->display();
|
||||
} else if ($action == 'edit') {
|
||||
$type = lti_get_type_type_config($typeid);
|
||||
$form->set_data($type);
|
||||
// If the user just opened an add or edit form.
|
||||
if ($action == 'add' || $action == 'edit') {
|
||||
if ($action == 'edit') {
|
||||
$type = lti_get_type_type_config($typeid);
|
||||
$form->set_data($type);
|
||||
}
|
||||
echo $OUTPUT->heading(get_string('toolsetup', 'lti'));
|
||||
$form->display();
|
||||
} else {
|
||||
$script = '';
|
||||
$closewindow = <<<EOF
|
||||
setTimeout(function() {
|
||||
window.close();
|
||||
}, $timeout);
|
||||
EOF;
|
||||
|
||||
if ($data = $form->get_data()) {
|
||||
$type = new stdClass();
|
||||
|
||||
if (!empty($typeid)) {
|
||||
$type->id = $typeid;
|
||||
|
||||
lti_load_type_if_cartridge($data);
|
||||
|
||||
lti_update_type($type, $data);
|
||||
|
||||
$fromdb = lti_get_type($typeid);
|
||||
$json = json_encode($fromdb);
|
||||
|
||||
// Output script to update the calling window.
|
||||
$script = <<<EOF
|
||||
window.opener.M.mod_lti.editor.updateToolType({$json});
|
||||
EOF;
|
||||
} else {
|
||||
$type->state = LTI_TOOL_STATE_CONFIGURED;
|
||||
$type->course = $COURSE->id;
|
||||
|
||||
lti_load_type_if_cartridge($data);
|
||||
|
||||
$id = lti_add_type($type, $data);
|
||||
|
||||
$fromdb = lti_get_type($id);
|
||||
$json = json_encode($fromdb);
|
||||
|
||||
// Output script to update the calling window.
|
||||
$script = <<<EOF
|
||||
window.opener.M.mod_lti.editor.addToolType({$json});
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
echo html_writer::script($script . $closewindow);
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
@ -52,7 +52,7 @@ $string['accept'] = 'Accept';
|
||||
$string['accepted'] = 'Accepted';
|
||||
$string['accept_grades'] = 'Accept grades from the tool';
|
||||
$string['accept_grades_admin'] = 'Accept grades from the tool';
|
||||
$string['accept_grades_admin_help'] = 'Specify whether the tool provider can add, update, read, and delete grades associated with instances of this tool type.
|
||||
$string['accept_grades_admin_help'] = 'Specify whether the tool provider can add, update, read, and delete grades associated with instances of this tool.
|
||||
|
||||
Some tool providers support reporting grades back to Moodle based on actions taken within the tool, creating a more integrated
|
||||
experience.';
|
||||
@ -62,16 +62,18 @@ Some tool providers support reporting grades back to Moodle based on actions tak
|
||||
|
||||
Note that this setting may be overridden in the tool configuration.';
|
||||
$string['action'] = 'Action';
|
||||
$string['activate'] = 'Activate';
|
||||
$string['active'] = 'Active';
|
||||
$string['activity'] = 'Activity';
|
||||
$string['addnewapp'] = 'Enable external application';
|
||||
$string['addserver'] = 'Add new trusted server';
|
||||
$string['addtype'] = 'Add external tool configuration';
|
||||
$string['addtype'] = 'Add preconfigured tool';
|
||||
$string['allow'] = 'Allow';
|
||||
$string['allowinstructorcustom'] = 'Allow teachers to add custom parameters';
|
||||
$string['allowsetting'] = 'Allow tool to store 8K of settings in Moodle';
|
||||
$string['always'] = 'Always';
|
||||
$string['automatic'] = 'Automatic, based on launch URL';
|
||||
$string['autoaddtype'] = 'Add tool';
|
||||
$string['baseurl'] = 'Base URL/tool registration name';
|
||||
$string['basiclti'] = 'LTI';
|
||||
$string['basiclti_base_string'] = 'LTI OAuth base string';
|
||||
@ -88,6 +90,7 @@ $string['cancelled'] = 'Cancelled';
|
||||
$string['cannot_delete'] = 'You may not delete this tool configuration.';
|
||||
$string['cannot_edit'] = 'You may not edit this tool configuration.';
|
||||
$string['capabilities'] = 'Capabilities';
|
||||
$string['capabilitiesrequired'] = 'This tool requires access to the following data in order to activate:';
|
||||
$string['capabilities_help'] = 'Select those capabilities which you wish to offer to the tool provider. More than one capability can be selected.';
|
||||
$string['click_to_continue'] = '<a href="{$a->link}" target="_top">Click to continue</a>';
|
||||
$string['comment'] = 'Comment';
|
||||
@ -99,8 +102,12 @@ $string['configresourceurl'] = 'Default resource URL';
|
||||
$string['configtoolurl'] = 'Default remote tool URL';
|
||||
$string['configtypes'] = 'Enable LTI applications';
|
||||
$string['configured'] = 'Configured';
|
||||
$string['course_tool_types'] = 'Course tool types';
|
||||
$string['confirmtoolactivation'] = 'Are you sure you would like to activate this tool?';
|
||||
$string['courseactivitiesorresources'] = 'Course acitivities or resources';
|
||||
$string['course_tool_types'] = 'Course tools';
|
||||
$string['courseid'] = 'Course ID number';
|
||||
$string['courseinformation'] = 'Course information';
|
||||
$string['courselink'] = 'Go to course';
|
||||
$string['coursemisconf'] = 'Course is misconfigured';
|
||||
$string['createdon'] = 'Created on';
|
||||
$string['curllibrarymissing'] = 'PHP Curl library must be installed to use LTI';
|
||||
@ -128,8 +135,8 @@ real estate to the tool, and others provide a more integrated feel with the Mood
|
||||
It is possible that browsers will prevent the new window from opening.';
|
||||
$string['delegate'] = 'Delegate to teacher';
|
||||
$string['delete'] = 'Delete';
|
||||
$string['delete_confirmation'] = 'Are you sure you want to delete this external tool configuration?';
|
||||
$string['deletetype'] = 'Delete external tool configuration';
|
||||
$string['delete_confirmation'] = 'Are you sure you want to delete this preconfigured tool?';
|
||||
$string['deletetype'] = 'Delete preconfigured tool';
|
||||
$string['display_description'] = 'Display activity description when launched';
|
||||
$string['display_description_help'] = 'If selected, the activity description (specified above) will display above the tool provider\'s content.
|
||||
|
||||
@ -148,15 +155,17 @@ $string['donot'] = 'Do not send';
|
||||
$string['donotaccept'] = 'Do not accept';
|
||||
$string['donotallow'] = 'Do not allow';
|
||||
$string['duplicateregurl'] = 'This registration URL is already in use';
|
||||
$string['edittype'] = 'Edit external tool configuration';
|
||||
$string['editdescription'] = 'Click here to give this tool a description';
|
||||
$string['edittype'] = 'Edit preconfigured tool';
|
||||
$string['embed'] = 'Embed';
|
||||
$string['embed_no_blocks'] = 'Embed, without blocks';
|
||||
$string['enableemailnotification'] = 'Send notification emails';
|
||||
$string['enableemailnotification_help'] = 'If enabled, students will receive email notification when their tool submissions are graded.';
|
||||
$string['enterkeyandsecret'] = 'Enter your consumer key and shared secret';
|
||||
$string['errormisconfig'] = 'Misconfigured tool. Please ask your Moodle administrator to fix the configuration of the tool.';
|
||||
$string['existing_window'] = 'Existing window';
|
||||
$string['extensions'] = 'LTI extension services';
|
||||
$string['external_tool_type'] = 'External tool type';
|
||||
$string['external_tool_type'] = 'Preconfigured tool';
|
||||
$string['external_tool_type_help'] = 'The main purpose of a tool configuration is to set up a secure communication channel between Moodle and the tool provider.
|
||||
It also provides an opportunity for configuration defaults and setting up additional services provided by the tool.
|
||||
|
||||
@ -164,22 +173,24 @@ It also provides an opportunity for configuration defaults and setting up additi
|
||||
based on the Launch URL. Tools configured by both an administrator or within this course will be used.
|
||||
When the Launch URL is specified, Moodle will provide feedback on whether it recognizes it or not. If Moodle does not recognize the Launch URL,
|
||||
you may need to enter the tool configuration details manually.
|
||||
* **A specific tool type** - By selecting a specific tool type, you can force Moodle to use that tool configuration when communicating with the
|
||||
* **A specific preconfigured tool** - By selecting a preconfigured tool, you can force Moodle to use that tool configuration when communicating with the
|
||||
external tool provider. If the Launch URL does not appear to belong to the tool provider, a warning will appear. In some cases, it is not necessary
|
||||
to enter a Launch URL when providing a specific tool type (if not launching to a particular resource within the tool provider).
|
||||
to enter a Launch URL when providing a specific preconfigured tool (if not launching to a particular resource within the tool provider).
|
||||
* **Custom configuration** - To setup custom tool configuration on just this instance, show Advanced options, and enter the consumer key and
|
||||
shared secret yourself. If you do not have a consumer key and shared secret, you may be able to request them from the tool provider.
|
||||
Not all tools require a consumer key and shared secret, in which case the fields may be left blank.
|
||||
|
||||
### Tool type editing
|
||||
### Preconfigured tool editing
|
||||
|
||||
Three icons are available after the External tool type dropdown list:
|
||||
Three icons are available after the preconfigured tool dropdown list:
|
||||
|
||||
* **Add** - Create a course level tool configuration. All External Tool instances in this course may use the tool configuration.
|
||||
* **Edit** - Select a course level tool type from the dropdown, then click this icon. The details of the tool configuration may be edited.
|
||||
* **Delete** - Remove the selected course level tool type.';
|
||||
$string['external_tool_types'] = 'External tool types';
|
||||
* **Edit** - Select a course level tool from the dropdown, then click this icon. The details of the tool configuration may be edited.
|
||||
* **Delete** - Remove the selected course level tool.';
|
||||
$string['external_tool_types'] = 'Preconfigured tools';
|
||||
$string['failedtoconnect'] = 'Moodle was unable to communicate with the "{$a}" system';
|
||||
$string['failedtocreatetooltype'] = 'Failed to create new tool.';
|
||||
$string['failedtodeletetoolproxy'] = 'Failed to delete tool registration. You may need to visit "Manage external tool registrations" and delete it manually.';
|
||||
$string['filter_basiclti_configlink'] = 'Configure your preferred sites and their passwords';
|
||||
$string['filter_basiclti_password'] = 'Password is mandatory';
|
||||
$string['filterconfig'] = 'LTI administration';
|
||||
@ -196,7 +207,7 @@ In addition, all web service requests from the tool provider will use SSL.
|
||||
|
||||
If using this option, confirm that this Moodle site and the tool provider support SSL.';
|
||||
$string['generaltool'] = 'General tool';
|
||||
$string['global_tool_types'] = 'Global tool types';
|
||||
$string['global_tool_types'] = 'Global preconfigured tools';
|
||||
$string['grading'] = 'Grade routing';
|
||||
$string['icon_url'] = 'Icon URL';
|
||||
$string['icon_url_help'] = 'The icon URL allows the icon that shows up in the course listing for this activity to be modified. Instead of using the default
|
||||
@ -205,11 +216,13 @@ $string['id'] = 'id';
|
||||
$string['invalidid'] = 'LTI ID was incorrect';
|
||||
$string['launch_in_moodle'] = 'Launch tool in moodle';
|
||||
$string['launch_in_popup'] = 'Launch tool in a pop-up';
|
||||
$string['launch_url'] = 'Launch URL';
|
||||
$string['launch_url'] = 'Launch/Cartridge URL';
|
||||
$string['launch_url_help'] = 'The Launch URL indicates the web address of the External Tool, and may contain additional information, such as the resource to show.
|
||||
If you are unsure what to enter for the Launch URL, please check with the tool provider for more information.
|
||||
|
||||
If you have selected a specific tool type, you may not need to enter a Launch URL. If the tool link is used to just launch
|
||||
You can also enter a cartridge URL if you have one, and the rest of the form details will fill automatically.
|
||||
|
||||
If you have selected a preconfigured tool, you may not need to enter a Launch URL. If the tool link is used to just launch
|
||||
into the tool provider\'s system, and not go to a specific resource, this will likely be the case.';
|
||||
$string['launchinpopup'] = 'Launch container';
|
||||
$string['launchinpopup_help'] = 'The launch container affects the display of the tool when launched from the course. Some launch containers provide more screen
|
||||
@ -223,6 +236,7 @@ real estate to the tool, and others provide a more integrated feel with the Mood
|
||||
Depending on the browser, it will open in a new tab or a popup window.
|
||||
It is possible that browsers will prevent the new window from opening.';
|
||||
$string['launchoptions'] = 'Launch options';
|
||||
$string['leaveblank'] = 'Leave blank if you do not need them';
|
||||
$string['lti'] = 'LTI';
|
||||
$string['lti:addinstance'] = 'Add new external tool activities';
|
||||
$string['lti:addcoursetool'] = 'Add course-specific tool configurations';
|
||||
@ -248,7 +262,7 @@ $string['main_admin_help'] = 'External tools allow Moodle users to seamlessly in
|
||||
launch protocol, the remote tool will have access to some general information about the launching user. For example,
|
||||
the institution name, course id, user id, and other information such as the user\'s name or e-mail address.
|
||||
|
||||
Tool types listed on this page are separated into three categories:
|
||||
Tools listed on this page are separated into three categories:
|
||||
|
||||
* **Active** - These tool providers have been approved and configured by an administrator. They can be used from within any
|
||||
course on this Moodle instance. If a consumer key and shared secret are entered, a trust relationship is established
|
||||
@ -257,8 +271,10 @@ Tool types listed on this page are separated into three categories:
|
||||
Teachers may still use tools from these providers if they have a consumer key and shared secret, or if none is required.
|
||||
* **Rejected** - These tools providers are flagged as ones which an administrator has no intention of making available to the entire
|
||||
Moodle instance. Teachers may still use tools from these providers if they have a consumer key and shared secret, or if none is required.';
|
||||
$string['manage_tools'] = 'Manage external tool types';
|
||||
$string['manage_external_tools'] = 'Manage tools';
|
||||
$string['manage_tools'] = 'Manage preconfigured tools';
|
||||
$string['manage_tool_proxies'] = 'Manage external tool registrations';
|
||||
$string['manuallyaddtype'] = 'alternatively, you can <a href="{$a}">configure a tool manually</a>.';
|
||||
$string['miscellaneous'] = 'Miscellaneous';
|
||||
$string['misconfiguredtools'] = 'Misconfigured tool instances were detected';
|
||||
$string['missingparameterserror'] = 'The page is misconfigured: "{$a}"';
|
||||
@ -282,6 +298,7 @@ $string['new_window'] = 'New window';
|
||||
$string['no_lti_configured'] = 'There are no active external tools configured.';
|
||||
$string['no_lti_pending'] = 'There are no pending external tools.';
|
||||
$string['no_lti_rejected'] = 'There are no rejected external tools.';
|
||||
$string['no_lti_tools'] = 'There are no external tools configured.';
|
||||
$string['no_tp_accepted'] = 'There are no accepted external tool registrations.';
|
||||
$string['no_tp_cancelled'] = 'There are no cancelled external tool registrations.';
|
||||
$string['no_tp_configured'] = 'There are no unregistered external tool registrations configured.';
|
||||
@ -337,7 +354,7 @@ $string['quickgrade'] = 'Allow quick grading';
|
||||
$string['quickgrade_help'] = 'If enabled, multiple tools can be graded on one page. Add grades and comments then click the "Save all my feedback" button to save all changes for that page.';
|
||||
$string['redirect'] = 'You will be redirected in few seconds. If you are not, press the button.';
|
||||
$string['register'] = 'Register';
|
||||
$string['register_warning'] = 'The registration page seems to be taking a while to open. If it does not appear, check that you entered the correct URL in the configuration settings.';
|
||||
$string['register_warning'] = 'The registration page seems to be taking a while to open. If it does not appear, check that you entered the correct URL in the configuration settings. If Moodle is using https, unsure the tool you are configuring supports https and you are using https in the URL.';
|
||||
$string['registertype'] = 'Configure a new external tool registration';
|
||||
$string['registration_options'] = 'Registration options';
|
||||
$string['registrationname'] = 'Tool provider name';
|
||||
@ -409,23 +426,20 @@ The tool provider may need launchers\' names to show meaningful information with
|
||||
Note that this setting may be overridden in the tool configuration.';
|
||||
$string['share_roster'] = 'Allow the tool to access this course\'s roster';
|
||||
$string['share_roster_admin'] = 'Tool may access course roster';
|
||||
$string['share_roster_admin_help'] = 'Specify whether the tool can access the list of users enrolled in courses from which this tool type is launched.';
|
||||
$string['share_roster_admin_help'] = 'Specify whether the tool can access the list of users enrolled in courses from which this tool is launched.';
|
||||
$string['share_roster_help'] = 'Specify whether the tool can access the list of users enrolled in this course.
|
||||
|
||||
Note that this setting may be overridden in the tool configuration.';
|
||||
$string['show_in_course'] = 'Show tool type when creating tool instances';
|
||||
$string['show_in_course_help'] = 'If selected, this tool configuration will appear in the "External tool type" dropdown when teachers
|
||||
configure external tools within courses.
|
||||
$string['show_in_course'] = 'Show preconfigured tool when creating tool instances';
|
||||
$string['show_in_course_help'] = 'If selected, this tool configuration will appear in the "Preconfigured tools" dropdown when teachers
|
||||
configure external tools within courses, and it will appear in the activity picker.
|
||||
|
||||
In most cases, this option does not need to be selected. Teachers can use this tool configuration
|
||||
based on the Launch URL matching the Tool base URL, which is the preferred method.
|
||||
|
||||
The only case in which this option should be selected is if the tool configuration is just intended for single sign on.
|
||||
For example, if all launches to the tool provider just take the user to a landing page instead of to a specific resource.';
|
||||
If not selected teachers can only use this tool configuration based on the Launch URL matching the Tool base URL.';
|
||||
$string['size'] = 'Size parameters';
|
||||
$string['submission'] = 'Submission';
|
||||
$string['submissions'] = 'Submissions';
|
||||
$string['submissionsfor'] = 'Submissions for {$a}';
|
||||
$string['successfullycreatedtooltype'] = 'Successfully created new tool!';
|
||||
$string['subplugintype_ltiresource'] = 'LTI service resource';
|
||||
$string['subplugintype_ltiresource_plural'] = 'LTI service resources';
|
||||
$string['subplugintype_ltiservice'] = 'LTI service';
|
||||
@ -435,6 +449,12 @@ $string['subplugintype_ltisource_plural'] = 'LTI sources';
|
||||
$string['toggle_debug_data'] = 'Toggle debug data';
|
||||
$string['tool_config_not_found'] = 'Tool configuration not found for this URL.';
|
||||
$string['tool_settings'] = 'Tool settings';
|
||||
$string['tooldescription'] = 'Tool description';
|
||||
$string['tooldescription_help'] = 'The description of the tool that will be displayed to teachers in the activity list.
|
||||
|
||||
This should describe what the tool is for and what it does and any additional information the teacher may need to know.';
|
||||
$string['toolisbeingused'] = 'This tool is being used {$a} times';
|
||||
$string['toolisnotbeingused'] = 'This tool has not yet been used';
|
||||
$string['toolproxy'] = 'External tool registrations';
|
||||
$string['toolproxy_help'] = 'External tool registrations allow Moodle site administrators to configure external tools from a tool proxy obtained from a tool provider supporting LTI 2.0. A registration URL provided by the tool provider is all that is required to initiate the process. The capabilities and services offered to the tool provider are selected when configuring a new registration.
|
||||
|
||||
@ -443,14 +463,20 @@ Tool registrations listed on this page are separated into four categories:
|
||||
* **Configured** - These tool registrations have been set up but the registration process has not yet been started.
|
||||
* **Pending** - The registration process for these tool registrations has been started but has not completed. Open and save the settings to move it
|
||||
back to the \'Configured\' category.
|
||||
* **Accepted** - These tool registrations have been approved; the resources specified in the tool proxy will appear on the external tool types page
|
||||
* **Accepted** - These tool registrations have been approved; the resources specified in the tool proxy will appear on the preconfigured tools page
|
||||
with an initial status of \'Pending\'.
|
||||
* **Rejected** - These tool registrations are ones which were rejected during the registration process. Open and save the settings to move it
|
||||
back to the \'Configured\' category so the registration process can be restarted.';
|
||||
$string['toolproxyregistration'] = 'External tool registration';
|
||||
$string['toolregistration'] = 'External tool registration';
|
||||
$string['toolsetup'] = 'External tool configuration';
|
||||
$string['toolurl'] = 'Tool base URL';
|
||||
$string['tooltypes'] = 'Tools';
|
||||
$string['tooltypeadded'] = 'Preconfigured tool added';
|
||||
$string['tooltypedeleted'] = 'Preconfigured tool deleted';
|
||||
$string['tooltypenotdeleted'] = 'Could not delete preconfigured tool';
|
||||
$string['tooltypeupdated'] = 'Preconfigured tool updated';
|
||||
$string['toolurl'] = 'Tool base URL/Cartridge URL';
|
||||
$string['toolurlplaceholder'] = 'Tool URL...';
|
||||
$string['toolurl_help'] = 'The tool base URL is used to match tool launch URLs to the correct tool configuration. Prefixing the URL with http(s) is optional.
|
||||
|
||||
Additionally, the base URL is used as the launch URL if a launch URL is not specified in the external tool instance.
|
||||
@ -473,12 +499,20 @@ A base URL of *quiz.tool.com* would match the following:
|
||||
* quiz.tool.com
|
||||
* quiz.tool.com/take.php?id=10
|
||||
|
||||
If two different tool configurations are for the same domain, the most specific match will be used.';
|
||||
If two different tool configurations are for the same domain, the most specific match will be used.
|
||||
|
||||
You can also insert a cartridge URL if you have one and the details for the tool will be automatically filled.';
|
||||
$string['typename'] = 'Tool name';
|
||||
$string['typename_help'] = 'The tool name is used to identify the tool provider within Moodle. The name entered will be visible
|
||||
to teachers when adding external tools within courses.';
|
||||
$string['types'] = 'Types';
|
||||
$string['unabletocreatetooltype'] = 'Unable to create tool';
|
||||
$string['unabletofindtooltype'] = 'Unable to find tool for {$a->id}';
|
||||
$string['unknownstate'] = 'Unknown state';
|
||||
$string['update'] = 'Update';
|
||||
$string['useraccountinformation'] = 'User account information';
|
||||
$string['userpersonalinformation'] = 'User personal information';
|
||||
$string['using_tool_cartridge'] = 'Using tool cartridge';
|
||||
$string['using_tool_configuration'] = 'Using tool configuration: ';
|
||||
$string['validurl'] = 'A valid URL must start with http(s)://';
|
||||
$string['viewsubmissions'] = 'View submissions and grading screen';
|
||||
|
@ -97,6 +97,8 @@ function lti_add_instance($lti, $mform) {
|
||||
$lti->toolurl = '';
|
||||
}
|
||||
|
||||
lti_load_tool_if_cartridge($lti);
|
||||
|
||||
$lti->timecreated = time();
|
||||
$lti->timemodified = $lti->timecreated;
|
||||
$lti->servicesalt = uniqid('', true);
|
||||
@ -137,6 +139,8 @@ function lti_update_instance($lti, $mform) {
|
||||
global $DB, $CFG;
|
||||
require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
|
||||
lti_load_tool_if_cartridge($lti);
|
||||
|
||||
$lti->timemodified = time();
|
||||
$lti->id = $lti->instance;
|
||||
|
||||
@ -445,7 +449,20 @@ function lti_uninstall() {
|
||||
function lti_get_lti_types() {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_records('lti_types');
|
||||
return $DB->get_records('lti_types', null, 'state DESC, timemodified DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns available Basic LTI types that match the given
|
||||
* tool proxy id
|
||||
*
|
||||
* @param int $toolproxyid Tool proxy id
|
||||
* @return array of basicLTI types
|
||||
*/
|
||||
function lti_get_lti_types_from_proxy_id($toolproxyid) {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_records('lti_types', array('toolproxyid' => $toolproxyid), 'state DESC, timemodified DESC');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,11 +273,29 @@ function lti_launch_tool($instance) {
|
||||
* $param object $instance Tool Proxy instance object
|
||||
*/
|
||||
function lti_register($toolproxy) {
|
||||
global $PAGE, $CFG;
|
||||
$endpoint = $toolproxy->regurl;
|
||||
|
||||
// Change the status to pending.
|
||||
$toolproxy->state = LTI_TOOL_PROXY_STATE_PENDING;
|
||||
lti_update_tool_proxy($toolproxy);
|
||||
|
||||
$requestparams = lti_build_registration_request($toolproxy);
|
||||
|
||||
$content = lti_post_launch_html($requestparams, $endpoint, false);
|
||||
|
||||
echo $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the parameters for the regirstration request
|
||||
*
|
||||
* @param object $toolproxy Tool Proxy instance object
|
||||
* @return array Registration request parameters
|
||||
*/
|
||||
function lti_build_registration_request($toolproxy) {
|
||||
$key = $toolproxy->guid;
|
||||
$secret = $toolproxy->secret;
|
||||
$endpoint = $toolproxy->regurl;
|
||||
|
||||
$requestparams = array();
|
||||
$requestparams['lti_message_type'] = 'ToolProxyRegistrationRequest';
|
||||
@ -285,10 +303,6 @@ function lti_register($toolproxy) {
|
||||
$requestparams['reg_key'] = $key;
|
||||
$requestparams['reg_password'] = $secret;
|
||||
|
||||
// Change the status to pending.
|
||||
$toolproxy->state = LTI_TOOL_PROXY_STATE_PENDING;
|
||||
lti_update_tool_proxy($toolproxy);
|
||||
|
||||
// Add the profile URL.
|
||||
$profileservice = lti_get_service_by_name('profile');
|
||||
$profileservice->set_tool_proxy($toolproxy);
|
||||
@ -296,13 +310,12 @@ function lti_register($toolproxy) {
|
||||
|
||||
// Add the return URL.
|
||||
$returnurlparams = array('id' => $toolproxy->id, 'sesskey' => sesskey());
|
||||
$url = new \moodle_url('/mod/lti/registrationreturn.php', $returnurlparams);
|
||||
$url = new \moodle_url('/mod/lti/externalregistrationreturn.php', $returnurlparams);
|
||||
$returnurl = $url->out(false);
|
||||
|
||||
$requestparams['launch_presentation_return_url'] = $returnurl;
|
||||
$content = lti_post_launch_html($requestparams, $endpoint, false);
|
||||
|
||||
echo $content;
|
||||
return $requestparams;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1357,6 +1370,8 @@ function lti_get_type_type_config($id) {
|
||||
|
||||
$type->lti_toolurl = $basicltitype->baseurl;
|
||||
|
||||
$type->lti_description = $basicltitype->description;
|
||||
|
||||
$type->lti_parameters = $basicltitype->parameter;
|
||||
|
||||
$type->lti_icon = $basicltitype->icon;
|
||||
@ -1436,11 +1451,16 @@ function lti_prepare_type_for_save($type, $config) {
|
||||
$type->baseurl = $config->lti_toolurl;
|
||||
$type->tooldomain = lti_get_domain_from_url($config->lti_toolurl);
|
||||
}
|
||||
if (isset($config->lti_description)) {
|
||||
$type->description = $config->lti_description;
|
||||
}
|
||||
if (isset($config->lti_typename)) {
|
||||
$type->name = $config->lti_typename;
|
||||
}
|
||||
$type->coursevisible = !empty($config->lti_coursevisible) ? $config->lti_coursevisible : 0;
|
||||
$config->lti_coursevisible = $type->coursevisible;
|
||||
if (isset($config->lti_coursevisible)) {
|
||||
$type->coursevisible = !empty($config->lti_coursevisible) ? $config->lti_coursevisible : 0;
|
||||
$config->lti_coursevisible = $type->coursevisible;
|
||||
}
|
||||
|
||||
if (isset($config->lti_icon)) {
|
||||
$type->icon = $config->lti_icon;
|
||||
@ -1456,6 +1476,7 @@ function lti_prepare_type_for_save($type, $config) {
|
||||
|
||||
unset ($config->lti_typename);
|
||||
unset ($config->lti_toolurl);
|
||||
unset ($config->lti_description);
|
||||
unset ($config->lti_icon);
|
||||
unset ($config->lti_secureicon);
|
||||
}
|
||||
@ -1567,6 +1588,23 @@ function lti_get_tool_proxy_from_guid($toolproxyguid) {
|
||||
return $toolproxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tool proxy instance given its registration URL
|
||||
*
|
||||
* @param string $regurl Tool proxy registration URL
|
||||
*
|
||||
* @return array The record of the tool proxy with this url
|
||||
*/
|
||||
function lti_get_tool_proxies_from_registration_url($regurl) {
|
||||
global $DB;
|
||||
|
||||
return $DB->get_records_sql(
|
||||
'SELECT * FROM {lti_tool_proxies}
|
||||
WHERE '.$DB->sql_compare_text('regurl', 256).' = :regurl',
|
||||
array('regurl' => $regurl)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates some of the tool proxy configuration based on the admin configuration details
|
||||
*
|
||||
@ -1621,9 +1659,17 @@ function lti_add_tool_proxy($config) {
|
||||
}
|
||||
if (isset($config->lti_capabilities)) {
|
||||
$toolproxy->capabilityoffered = implode("\n", $config->lti_capabilities);
|
||||
} else {
|
||||
$toolproxy->capabilityoffered = implode("\n", array_keys(lti_get_capabilities()));
|
||||
}
|
||||
if (isset($config->lti_services)) {
|
||||
$toolproxy->serviceoffered = implode("\n", $config->lti_services);
|
||||
} else {
|
||||
$func = function($s) {
|
||||
return $s->get_id();
|
||||
};
|
||||
$servicenames = array_map($func, lti_get_services());
|
||||
$toolproxy->serviceoffered = implode("\n", $servicenames);
|
||||
}
|
||||
if (isset($config->toolproxyid) && !empty($config->toolproxyid)) {
|
||||
$toolproxy->id = $config->toolproxyid;
|
||||
@ -2186,3 +2232,378 @@ function lti_get_fqid($contexts, $id) {
|
||||
return $id;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the icon for the given tool type
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return string The url to the tool type's corresponding icon
|
||||
*/
|
||||
function get_tool_type_icon_url(stdClass $type) {
|
||||
global $OUTPUT;
|
||||
|
||||
$iconurl = $type->secureicon;
|
||||
|
||||
if (empty($iconurl)) {
|
||||
$iconurl = $type->icon;
|
||||
}
|
||||
|
||||
if (empty($iconurl)) {
|
||||
$iconurl = $OUTPUT->pix_url('icon', 'lti')->out();
|
||||
}
|
||||
|
||||
return $iconurl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the edit url for the given tool type
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return string The url to edit the tool type
|
||||
*/
|
||||
function get_tool_type_edit_url(stdClass $type) {
|
||||
$url = new moodle_url('/mod/lti/typessettings.php',
|
||||
array('action' => 'update', 'id' => $type->id, 'sesskey' => sesskey(), 'returnto' => 'toolconfigure'));
|
||||
return $url->out();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the course url for the given tool type
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return string|void The url to the course of the tool type, void if it is a site wide type
|
||||
*/
|
||||
function get_tool_type_course_url(stdClass $type) {
|
||||
if ($type->course == 1) {
|
||||
return;
|
||||
} else {
|
||||
$url = new moodle_url('/course/view.php', array('id' => $type->course));
|
||||
return $url->out();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the icon and edit urls for the tool type and the course url if it is a course type.
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return string The url to the course of the tool type
|
||||
*/
|
||||
function get_tool_type_urls(stdClass $type) {
|
||||
$courseurl = get_tool_type_course_url($type);
|
||||
|
||||
$urls = array(
|
||||
'icon' => get_tool_type_icon_url($type),
|
||||
'edit' => get_tool_type_edit_url($type),
|
||||
);
|
||||
|
||||
if ($courseurl) {
|
||||
$urls['course'] = $courseurl;
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information on the current state of the tool type
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return array An array with a text description of the state, and boolean for whether it is in each state:
|
||||
* pending, configured, rejected, unknown
|
||||
*/
|
||||
function get_tool_type_state_info(stdClass $type) {
|
||||
$state = '';
|
||||
$isconfigured = false;
|
||||
$ispending = false;
|
||||
$isrejected = false;
|
||||
$isunknown = false;
|
||||
switch ($type->state) {
|
||||
case LTI_TOOL_STATE_CONFIGURED:
|
||||
$state = get_string('active', 'mod_lti');
|
||||
$isconfigured = true;
|
||||
break;
|
||||
case LTI_TOOL_STATE_PENDING:
|
||||
$state = get_string('pending', 'mod_lti');
|
||||
$ispending = true;
|
||||
break;
|
||||
case LTI_TOOL_STATE_REJECTED:
|
||||
$state = get_string('rejected', 'mod_lti');
|
||||
$isrejected = true;
|
||||
break;
|
||||
default:
|
||||
$state = get_string('unknownstate', 'mod_lti');
|
||||
$isunknown = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return array(
|
||||
'text' => $state,
|
||||
'pending' => $ispending,
|
||||
'configured' => $isconfigured,
|
||||
'rejected' => $isrejected,
|
||||
'unknown' => $isunknown
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a summary of each LTI capability this tool type requires in plain language
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return array An array of text descriptions of each of the capabilities this tool type requires
|
||||
*/
|
||||
function get_tool_type_capability_groups($type) {
|
||||
$capabilities = lti_get_enabled_capabilities($type);
|
||||
$groups = array();
|
||||
$hascourse = false;
|
||||
$hasactivities = false;
|
||||
$hasuseraccount = false;
|
||||
$hasuserpersonal = false;
|
||||
|
||||
foreach ($capabilities as $capability) {
|
||||
// Bail out early if we've already found all groups.
|
||||
if (count($groups) >= 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$hascourse && preg_match('/^CourseSection/', $capability)) {
|
||||
$hascourse = true;
|
||||
$groups[] = get_string('courseinformation', 'mod_lti');
|
||||
} else if (!$hasactivities && preg_match('/^ResourceLink/', $capability)) {
|
||||
$hasactivities = true;
|
||||
$groups[] = get_string('courseactivitiesorresources', 'mod_lti');
|
||||
} else if (!$hasuseraccount && preg_match('/^User/', $capability) || preg_match('/^Membership/', $capability)) {
|
||||
$hasuseraccount = true;
|
||||
$groups[] = get_string('useraccountinformation', 'mod_lti');
|
||||
} else if (!$hasuserpersonal && preg_match('/^Person/', $capability)) {
|
||||
$hasuserpersonal = true;
|
||||
$groups[] = get_string('userpersonalinformation', 'mod_lti');
|
||||
}
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the ids of each instance of this tool type
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return array An array of ids of the instances of this tool type
|
||||
*/
|
||||
function get_tool_type_instance_ids($type) {
|
||||
global $DB;
|
||||
|
||||
return array_keys($DB->get_fieldset_select('lti', 'id', 'typeid = ?', array($type->id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialises this tool type
|
||||
*
|
||||
* @param stdClass $type The tool type
|
||||
*
|
||||
* @return array An array of values representing this type
|
||||
*/
|
||||
function serialise_tool_type(stdClass $type) {
|
||||
$capabilitygroups = get_tool_type_capability_groups($type);
|
||||
$instanceids = get_tool_type_instance_ids($type);
|
||||
|
||||
return array(
|
||||
'id' => $type->id,
|
||||
'name' => $type->name,
|
||||
'description' => isset($type->description) ? $type->description : get_string('editdescription', 'mod_lti'),
|
||||
'urls' => get_tool_type_urls($type),
|
||||
'state' => get_tool_type_state_info($type),
|
||||
'hascapabilitygroups' => !empty($capabilitygroups),
|
||||
'capabilitygroups' => $capabilitygroups,
|
||||
// Course ID of 1 means it's not linked to a course.
|
||||
'courseid' => $type->course == 1 ? 0 : $type->course,
|
||||
'instanceids' => $instanceids,
|
||||
'instancecount' => count($instanceids)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the cartridge information into the tool type, if the launch url is for a cartridge file
|
||||
*
|
||||
* @param stdClass $type The tool type object to be filled in
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function lti_load_type_if_cartridge($type) {
|
||||
if (!empty($type->lti_toolurl) && lti_is_cartridge($type->lti_toolurl)) {
|
||||
lti_load_type_from_cartridge($type->lti_toolurl, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the cartridge information into the new tool, if the launch url is for a cartridge file
|
||||
*
|
||||
* @param stdClass $lti The tools config
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function lti_load_tool_if_cartridge($lti) {
|
||||
if (!empty($lti->toolurl) && lti_is_cartridge($lti->toolurl)) {
|
||||
lti_load_tool_from_cartridge($lti->toolurl, $lti);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the given url is for a IMS basic cartridge
|
||||
*
|
||||
* @param string $url The url to be checked
|
||||
* @return True if the url is for a cartridge
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function lti_is_cartridge($url) {
|
||||
// If it is empty, it's not a cartridge.
|
||||
if (empty($url)) {
|
||||
return false;
|
||||
}
|
||||
// If it has xml at the end of the url, it's a cartridge.
|
||||
if (preg_match('/\.xml$/', $url)) {
|
||||
return true;
|
||||
}
|
||||
// Even if it doesn't have .xml, load the url to check if it's a cartridge..
|
||||
try {
|
||||
$toolinfo = lti_load_cartridge($url,
|
||||
array(
|
||||
"launch_url" => "launchurl"
|
||||
)
|
||||
);
|
||||
if (!empty($toolinfo['launchurl'])) {
|
||||
return true;
|
||||
}
|
||||
} catch (moodle_exception $e) {
|
||||
return false; // Error loading the xml, so it's not a cartridge.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to load settings for an external tool type from an IMS cartridge.
|
||||
*
|
||||
* @param string $url The URL to the cartridge
|
||||
* @param stdClass $type The tool type object to be filled in
|
||||
* @throws moodle_exception if the cartridge could not be loaded correctly
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function lti_load_type_from_cartridge($url, $type) {
|
||||
$toolinfo = lti_load_cartridge($url,
|
||||
array(
|
||||
"title" => "lti_typename",
|
||||
"launch_url" => "lti_toolurl",
|
||||
"description" => "lti_description"
|
||||
),
|
||||
array(
|
||||
"icon_url" => "lti_icon",
|
||||
"secure_icon_url" => "lti_secureicon"
|
||||
)
|
||||
);
|
||||
foreach ($toolinfo as $property => $value) {
|
||||
$type->$property = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to load in the configuration for an external tool from an IMS cartridge.
|
||||
*
|
||||
* @param string $url The URL to the cartridge
|
||||
* @param stdClass $lti LTI object
|
||||
* @throws moodle_exception if the cartridge could not be loaded correctly
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function lti_load_tool_from_cartridge($url, $lti) {
|
||||
$toolinfo = lti_load_cartridge($url,
|
||||
array(
|
||||
"title" => "name",
|
||||
"launch_url" => "toolurl",
|
||||
"secure_launch_url" => "securetoolurl",
|
||||
"description" => "intro"
|
||||
),
|
||||
array(
|
||||
"icon_url" => "icon",
|
||||
"secure_icon_url" => "secureicon"
|
||||
)
|
||||
);
|
||||
foreach ($toolinfo as $property => $value) {
|
||||
$lti->$property = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a tag within an XML DOMDocument
|
||||
*
|
||||
* @param string $url The url of the cartridge to be loaded
|
||||
* @param array $map The map of tags to keys in the return array
|
||||
* @param array $propertiesmap The map of properties to keys in the return array
|
||||
* @return array An associative array with the given keys and their values from the cartridge
|
||||
* @throws moodle_exception if the cartridge could not be loaded correctly
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function lti_load_cartridge($url, $map, $propertiesmap = array()) {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir. "/filelib.php");
|
||||
// TODO MDL-46023 Replace this code with a call to the new library.
|
||||
$origentity = libxml_disable_entity_loader(true);
|
||||
|
||||
$curl = new curl();
|
||||
$response = $curl->get($url);
|
||||
|
||||
$document = new DOMDocument();
|
||||
@$document->loadXML($response, LIBXML_DTDLOAD | LIBXML_DTDATTR);
|
||||
|
||||
$cartridge = new DomXpath($document);
|
||||
|
||||
$errors = libxml_get_errors();
|
||||
if (count($errors) > 0) {
|
||||
$message = 'Failed to load cartridge.';
|
||||
foreach ($errors as $error) {
|
||||
$message .= "\n" . trim($error->message, "\n\r\t .") . " at line " . $error->line;
|
||||
}
|
||||
throw new moodle_exception($message);
|
||||
}
|
||||
|
||||
$toolinfo = array();
|
||||
foreach ($map as $tag => $key) {
|
||||
$value = get_tag($tag, $cartridge);
|
||||
if ($value) {
|
||||
$toolinfo[$key] = $value;
|
||||
}
|
||||
}
|
||||
if (!empty($propertiesmap)) {
|
||||
foreach ($propertiesmap as $property => $key) {
|
||||
$value = get_tag("property", $cartridge, $property);
|
||||
if ($value) {
|
||||
$toolinfo[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
libxml_disable_entity_loader($origentity);
|
||||
return $toolinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a tag within an XML DOMDocument
|
||||
*
|
||||
* @param stdClass $tagname The name of the tag to search for
|
||||
* @param XPath $xpath The XML to find the tag in
|
||||
* @param XPath $attribute The attribute to search for (if we should search for a child node with the given
|
||||
* value for the name attribute
|
||||
* @since Moodle 3.1
|
||||
*/
|
||||
function get_tag($tagname, $xpath, $attribute = null) {
|
||||
if ($attribute) {
|
||||
$result = $xpath->query('//*[local-name() = \'' . $tagname . '\'][@name="' . $attribute . '"]');
|
||||
} else {
|
||||
$result = $xpath->query('//*[local-name() = \'' . $tagname . '\']');
|
||||
}
|
||||
if ($result->length > 0) {
|
||||
return $result->item(0)->nodeValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -179,6 +179,10 @@
|
||||
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.util.get_string('tool_config_not_found', 'lti'));
|
||||
}
|
||||
}
|
||||
if (toolInfo.cartridge) {
|
||||
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url +
|
||||
'" />' + M.util.get_string('using_tool_cartridge', 'lti'));
|
||||
}
|
||||
};
|
||||
|
||||
// Cache urls which have already been checked to increase performance
|
||||
@ -403,6 +407,14 @@
|
||||
this.clearToolCache();
|
||||
this.updateAutomaticToolMatch(Y.one('#id_toolurl'));
|
||||
this.updateAutomaticToolMatch(Y.one('#id_securetoolurl'));
|
||||
this.toggleEditButtons();
|
||||
|
||||
require(["core/notification"], function (notification) {
|
||||
notification.addNotification({
|
||||
message: M.util.get_string('tooltypeadded', 'lti'),
|
||||
type: "success"
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateToolType: function(toolType){
|
||||
@ -416,6 +428,13 @@
|
||||
this.clearToolCache();
|
||||
this.updateAutomaticToolMatch(Y.one('#id_toolurl'));
|
||||
this.updateAutomaticToolMatch(Y.one('#id_securetoolurl'));
|
||||
|
||||
require(["core/notification"], function (notification) {
|
||||
notification.addNotification({
|
||||
message: M.util.get_string('tooltypeupdated', 'lti'),
|
||||
type: "success"
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
deleteTool: function(toolTypeId){
|
||||
@ -430,9 +449,21 @@
|
||||
self.clearToolCache();
|
||||
self.updateAutomaticToolMatch(Y.one('#id_toolurl'));
|
||||
self.updateAutomaticToolMatch(Y.one('#id_securetoolurl'));
|
||||
|
||||
require(["core/notification"], function (notification) {
|
||||
notification.addNotification({
|
||||
message: M.util.get_string('tooltypedeleted', 'lti'),
|
||||
type: "success"
|
||||
});
|
||||
});
|
||||
},
|
||||
failure: function(){
|
||||
|
||||
require(["core/notification"], function (notification) {
|
||||
notification.addNotification({
|
||||
message: M.util.get_string('tooltypenotdeleted', 'lti'),
|
||||
type: "problem"
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -128,12 +128,12 @@ class mod_lti_mod_form extends moodleform_mod {
|
||||
}
|
||||
|
||||
$mform->addElement('text', 'toolurl', get_string('launch_url', 'lti'), array('size' => '64'));
|
||||
$mform->setType('toolurl', PARAM_TEXT);
|
||||
$mform->setType('toolurl', PARAM_URL);
|
||||
$mform->addHelpButton('toolurl', 'launch_url', 'lti');
|
||||
$mform->disabledIf('toolurl', 'typeid', 'neq', '0');
|
||||
|
||||
$mform->addElement('text', 'securetoolurl', get_string('secure_launch_url', 'lti'), array('size' => '64'));
|
||||
$mform->setType('securetoolurl', PARAM_TEXT);
|
||||
$mform->setType('securetoolurl', PARAM_URL);
|
||||
$mform->setAdvanced('securetoolurl');
|
||||
$mform->addHelpButton('securetoolurl', 'secure_launch_url', 'lti');
|
||||
$mform->disabledIf('securetoolurl', 'typeid', 'neq', '0');
|
||||
@ -239,9 +239,14 @@ class mod_lti_mod_form extends moodleform_mod {
|
||||
array('global_tool_types', 'lti'),
|
||||
array('course_tool_types', 'lti'),
|
||||
array('using_tool_configuration', 'lti'),
|
||||
array('using_tool_cartridge', 'lti'),
|
||||
array('domain_mismatch', 'lti'),
|
||||
array('custom_config', 'lti'),
|
||||
array('tool_config_not_found', 'lti'),
|
||||
array('tooltypeadded', 'lti'),
|
||||
array('tooltypedeleted', 'lti'),
|
||||
array('tooltypenotdeleted', 'lti'),
|
||||
array('tooltypeupdated', 'lti'),
|
||||
array('forced_help', 'lti')
|
||||
),
|
||||
);
|
||||
|
@ -56,10 +56,16 @@ defined('MOODLE_INTERNAL') || die;
|
||||
$modltifolder = new admin_category('modltifolder', new lang_string('pluginname', 'mod_lti'), $module->is_enabled() === false);
|
||||
$ADMIN->add('modsettings', $modltifolder);
|
||||
$settings->visiblename = new lang_string('manage_tools', 'mod_lti');
|
||||
$settings->hidden = true;
|
||||
$ADMIN->add('modltifolder', $settings);
|
||||
$ADMIN->add('modltifolder', new admin_externalpage('ltitoolproxies',
|
||||
$proxieslink = new admin_externalpage('ltitoolproxies',
|
||||
get_string('manage_tool_proxies', 'lti'),
|
||||
new moodle_url('/mod/lti/toolproxies.php')));
|
||||
new moodle_url('/mod/lti/toolproxies.php'));
|
||||
$proxieslink->hidden = true;
|
||||
$ADMIN->add('modltifolder', $proxieslink);
|
||||
$ADMIN->add('modltifolder', new admin_externalpage('ltitoolconfigure',
|
||||
get_string('manage_external_tools', 'lti'),
|
||||
new moodle_url('/mod/lti/toolconfigure.php')));
|
||||
|
||||
foreach (core_plugin_manager::instance()->get_plugins_of_type('ltisource') as $plugin) {
|
||||
/*
|
||||
|
@ -24,3 +24,359 @@
|
||||
|
||||
/* Styles for instructor_edit_tool_type.php */
|
||||
#page-mod-lti-instructor_edit_tool_type .mform .fitem .fitemtitle { min-width:18em;padding-right:1em } /* Prevent setting titles from wrapping */
|
||||
|
||||
/* Styling for tool_configure page */
|
||||
#registration-choice-container .buffer-text {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
#choice-list {
|
||||
list-style: none;
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
padding-bottom: 1em;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#choice-list > li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#external-registration-container iframe {
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
}
|
||||
|
||||
#external-registration-container .registration-loading-container {
|
||||
text-align: center;
|
||||
padding: 3em;
|
||||
}
|
||||
|
||||
#external-registration-container .registration-loading-container .loading-text, #external-registration-container .registration-loading-container .loader {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
#external-registration-container .registration-loading-container .loader {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 1em;
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
#registration-submit {
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
#registration-form-container {
|
||||
min-height: 230px;
|
||||
}
|
||||
|
||||
#registration-form-container .well {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#registration-form-container .control-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#registration-choice-container .well {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#registration-choice-container .btn-toolbar {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#registration-choice-container p:last-child {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#registration-feedback-container {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#registration-feedback-container h4 {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
#tool-type-capabilities-container .registration-loading-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#tool-type-capabilities-container.loading .registration-loading-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#tool-type-capabilities-container.loading #tool-type-capabilities-template-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.centered-menu {
|
||||
max-width: 70%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.btn-loader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.loading .btn-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.loading .btn-loader {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.btn .loader {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.btn .loader img {
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
#tool-list-container h3 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#tool-list-loader-container {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#tool-list-loader-container .loader {
|
||||
display: none;
|
||||
}
|
||||
#tool-list-loader-container .loader img {
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.loading #tool-list-loader-container .loader {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.loading #tool-notools-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-card {
|
||||
display: inline-block;
|
||||
width: 250px;
|
||||
height: 300px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 10px;
|
||||
margin: 5px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.tool-card:hover,
|
||||
.tool-card:focus {
|
||||
border-color: #0088cc;
|
||||
box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
|
||||
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
}
|
||||
|
||||
.tool-card .overlay-container {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 10px;
|
||||
display: none;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tool-card .overlay-container .img-container {
|
||||
position: absolute;
|
||||
top: 115px;
|
||||
left: 90px;
|
||||
display: block;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.tool-card .overlay-container .img-container img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tool-card.announcement > .overlay-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-card.announcement .overlay-container .loader {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-card.announcement.loading .overlay-container .loader {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tool-card.announcement .overlay-container .success-icon-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-card.announcement.success .overlay-container .success-icon-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-card.announcement .overlay-container .fail-icon-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-card.announcement.fail .overlay-container .fail-icon-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-card.announcement .overlay-container .capabilities-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-card.announcement.capabilities .overlay-container .capabilities-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-card.announcement.capabilities .overlay-container {
|
||||
background-color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.tool-card.announcement.capabilities .overlay-container .img-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tool-card-content {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.tool-card-header {
|
||||
text-align: center;
|
||||
background-color: #f5f5f5;
|
||||
padding: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 125px;
|
||||
}
|
||||
|
||||
.tool-card-subheader {
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dir-rtl .tool-card-subheader {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tool-card-header .tool-card-icon {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.tool-card-header .name {
|
||||
margin-bottom: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tool-card-header .tool-card-actions {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.dir-rtl .tool-card-header .tool-card-actions {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.tool-card-header .tool-card-actions img {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.dir-rtl .tool-card-header .tool-card-actions img {
|
||||
margin-left: 0px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.tool-card-body {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
height: 125px;
|
||||
}
|
||||
|
||||
.tool-card-body .description {
|
||||
max-height: 100px;
|
||||
}
|
||||
|
||||
.tool-card-footer {
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
padding-top: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tool-card .contenteditable-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tool-card [contenteditable=true] {
|
||||
border: 1px solid transparent;
|
||||
padding: 0.25em;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tool-card [contenteditable=true]:hover {
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
background-color: #fff;
|
||||
border: 1px solid #e3e3e3;
|
||||
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.tool-card [contenteditable=true]:focus {
|
||||
outline: 0;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(82, 168, 236, 0.8);
|
||||
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.tool-card [contenteditable=true].loading + .overlay-container {
|
||||
border-radius: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-card [contenteditable=true] + .overlay-container .loader {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
83
mod/lti/templates/cartridge_registration_form.mustache
Normal file
83
mod/lti/templates/cartridge_registration_form.mustache
Normal file
@ -0,0 +1,83 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/cartridge_registration_form
|
||||
|
||||
This template provides the layout for the external tool configuration page in the
|
||||
LTI module.
|
||||
|
||||
Classes required for JS:
|
||||
* lead
|
||||
* centered-menu
|
||||
* well
|
||||
* form-horizontal
|
||||
* text-center
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
}}
|
||||
<div class="centered-menu">
|
||||
<div class="well">
|
||||
<form id="cartridge-registration-form" class="form-horizontal">
|
||||
<p class="lead text-center">{{#str}} enterkeyandsecret, mod_lti {{/str}}</p>
|
||||
<p class="text-center">{{#str}} leaveblank, mod_lti {{/str}}</p>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="registration-key">{{#str}} resourcekey_admin, mod_lti {{/str}}</label>
|
||||
<div class="controls">
|
||||
<input name="tool-key"
|
||||
class="input-block-level"
|
||||
type="text"
|
||||
id="registration-key">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="registration-secret">{{#str}} password_admin, mod_lti {{/str}}</label>
|
||||
<div class="controls">
|
||||
<input name="tool-secret"
|
||||
class="input-block-level"
|
||||
type="text"
|
||||
id="registration-secret">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button id="cartridge-registration-submit" type="submit" class="btn btn-success">
|
||||
<span class="btn-text">{{#str}} savechanges {{/str}}</span>
|
||||
<div class="btn-loader">
|
||||
{{> mod_lti/loader }}
|
||||
</div>
|
||||
</button>
|
||||
<button id="cartridge-registration-cancel" type="button" class="btn">
|
||||
<span class="btn-text">{{#str}} cancel {{/str}}</span>
|
||||
<div class="btn-loader">
|
||||
{{> mod_lti/loader }}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['mod_lti/cartridge_registration_form'], function(registration) {
|
||||
registration.init();
|
||||
});
|
||||
{{/js}}
|
54
mod/lti/templates/external_registration.mustache
Normal file
54
mod/lti/templates/external_registration.mustache
Normal file
@ -0,0 +1,54 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/external_registration
|
||||
|
||||
This template provides the layout for the external tool configuration page in the
|
||||
LTI module.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
}}
|
||||
<div id="external-registration-page-container">
|
||||
<button id="cancel-external-registration" class="btn btn-danger">
|
||||
<span class="btn-text">{{#str}} cancel {{/str}}</span>
|
||||
<div class="btn-loader">
|
||||
{{> mod_lti/loader }}
|
||||
</div>
|
||||
</button>
|
||||
<div id="external-registration-template-container"></div>
|
||||
</div>
|
||||
|
||||
<div id="tool-type-capabilities-container" class="hidden">
|
||||
<div class="registration-loading-container">
|
||||
{{> mod_lti/loader }}
|
||||
<p>{{#str}} loading, admin {{/str}}</p>
|
||||
</div>
|
||||
<div id="tool-type-capabilities-template-container" aria-live="polite"></div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['mod_lti/external_registration'], function(registration) {
|
||||
registration.init();
|
||||
});
|
||||
{{/js}}
|
39
mod/lti/templates/loader.mustache
Normal file
39
mod/lti/templates/loader.mustache
Normal file
@ -0,0 +1,39 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/loader
|
||||
|
||||
This template provides the registration form to submit an external
|
||||
LTI registration.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
}
|
||||
|
||||
}}
|
||||
<div class="loader">
|
||||
{{#pix}} i/loading, core, {{#str}} loadinghelp, moodle {{/str}} {{/pix}}
|
||||
</div>
|
49
mod/lti/templates/registration_feedback.mustache
Normal file
49
mod/lti/templates/registration_feedback.mustache
Normal file
@ -0,0 +1,49 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/registration_feedback
|
||||
|
||||
This template provides the layout for a feedback message in the
|
||||
tool configuration page.
|
||||
|
||||
Classes required for JS:
|
||||
* close
|
||||
* alert
|
||||
* alert-success
|
||||
* alert-error
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* status
|
||||
* message
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"status": "Success",
|
||||
"message": "Successfully created a new tool type!"
|
||||
}
|
||||
|
||||
}}
|
||||
<div class="alert
|
||||
{{^error}}alert-success{{/error}}
|
||||
{{#error}}alert-error{{/error}}" role="alert">
|
||||
<button type="button" class="close" aria-label="{{#str}} closebuttontitle, moodle {{/str}}">×</button>
|
||||
<h4>{{status}}</h4>
|
||||
{{message}}
|
||||
</div>
|
104
mod/lti/templates/tool_card.mustache
Normal file
104
mod/lti/templates/tool_card.mustache
Normal file
@ -0,0 +1,104 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/tool_card
|
||||
|
||||
This template provides the layout for a single tool card on the tool
|
||||
configuration page.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* hascapabilitygroups
|
||||
* state
|
||||
** pending|configured|rejected|unknown
|
||||
** text
|
||||
* courseid
|
||||
* urls
|
||||
** course
|
||||
** icon
|
||||
* name
|
||||
* description
|
||||
* instancecount
|
||||
|
||||
}}
|
||||
<div class="tool-card" data-type-id="{{id}}">
|
||||
<div class="overlay-container">
|
||||
<div class="img-container">
|
||||
{{> mod_lti/loader }}
|
||||
<div class="success-icon-container">{{#pix}} i/valid, core, {{#str}} success {{/str}}{{/pix}}</div>
|
||||
<div class="fail-icon-container">{{#pix}} i/invalid, core, {{#str}} error {{/str}}{{/pix}}</div>
|
||||
</div>
|
||||
{{#hascapabilitygroups}}
|
||||
{{> mod_lti/tool_type_capabilities_agree }}
|
||||
{{/hascapabilitygroups}}
|
||||
</div>
|
||||
<div class="tool-card-content">
|
||||
<div class="tool-card-header">
|
||||
<div class="tool-card-subheader">
|
||||
<div class="label
|
||||
{{#state.pending}}label-info{{/state.pending}}
|
||||
{{#state.configured}}label-success{{/state.configured}}
|
||||
{{#state.rejected}}label-important{{/state.rejected}}
|
||||
{{#state.unknown}}label-warning{{/state.unknown}}">
|
||||
{{state.text}}
|
||||
</div>
|
||||
<div class="tool-card-actions pull-right">
|
||||
{{#courseid}}
|
||||
<a href="{{{urls.course}}}" title="{{#str}} courselink, mod_lti {{/str}}">{{#pix}} i/course, core, {{#str}} courselink, mod_lti {{/str}}{{/pix}}</a>
|
||||
{{/courseid}}
|
||||
<a class="edit" href="{{{urls.edit}}}" title="{{#str}} edit {{/str}}">{{#pix}} t/edit, core, {{#str}} edit {{/str}}{{/pix}}</a>
|
||||
<a class="delete" href="#" title="{{#str}} delete {{/str}}">{{#pix}} t/delete, core, {{#str}} delete {{/str}}{{/pix}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<img class="tool-card-icon" src="{{{urls.icon}}}" alt="{{name}}"></img>
|
||||
<div class="contenteditable-container">
|
||||
<h4 class="name" contenteditable="true">{{name}}</h4>
|
||||
<div class="overlay-container">{{> mod_lti/loader }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card-body">
|
||||
<div class="contenteditable-container">
|
||||
<p class="description" contenteditable="true">{{description}}</p>
|
||||
<div class="overlay-container">{{> mod_lti/loader }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card-footer">
|
||||
{{#state.pending}}
|
||||
<a class="activate btn btn-success" href="#">{{#str}} activate, mod_lti {{/str}}</a>
|
||||
{{/state.pending}}
|
||||
{{^state.pending}}
|
||||
{{#instancecount}}
|
||||
<p>{{#str}} toolisbeingused, mod_lti, {{instancecount}} {{/str}}</p>
|
||||
{{/instancecount}}
|
||||
{{^instancecount}}
|
||||
<p>{{#str}} toolisnotbeingused, mod_lti{{/str}}</p>
|
||||
{{/instancecount}}
|
||||
{{/state.pending}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'mod_lti/tool_card_controller'], function($, controller) {
|
||||
var cardElement = $('[data-type-id={{id}}]');
|
||||
controller.init(cardElement);
|
||||
});
|
||||
{{/js}}
|
78
mod/lti/templates/tool_configure.mustache
Normal file
78
mod/lti/templates/tool_configure.mustache
Normal file
@ -0,0 +1,78 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/tool_configure
|
||||
|
||||
This template provides the layout for the external tool configuration page in the
|
||||
LTI module.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
}}
|
||||
<h2>{{#str}} manage_external_tools, mod_lti {{/str}}</h2>
|
||||
<div class="container-fluid">
|
||||
<div id="main-content-container">
|
||||
<div id="registration-form-container" aria-live="polite">
|
||||
<div id="registration-choice-container" class="centered-menu">
|
||||
<div class="well">
|
||||
<p class="lead">{{#str}} autoaddtype, mod_lti {{/str}}</p>
|
||||
<form class="form-horizontal" id="add-tool-form">
|
||||
<div class="control-group">
|
||||
<input name="url"
|
||||
class="input-large"
|
||||
type="url"
|
||||
id="tool-url"
|
||||
placeholder="{{#str}} toolurlplaceholder, mod_lti {{/str}}"
|
||||
required>
|
||||
<button id="tool-create-button" type="submit" class="btn btn-success">
|
||||
<span class="btn-text">{{#str}} add {{/str}}</span>
|
||||
<div class="btn-loader">
|
||||
{{> mod_lti/loader }}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<p>{{#str}} manuallyaddtype, mod_lti, {{{configuremanualurl}}} {{/str}}</p>
|
||||
<p><a href="{{{ managetoolsurl }}}">{{#str}} manage_tools, mod_lti {{/str}}</a><br/><a href="{{{ managetoolproxiesurl}}}">{{#str}} manage_tool_proxies, mod_lti {{/str}}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="registration-feedback-container" aria-live="polite"></div>
|
||||
<div id="cartridge-registration-container" aria-live="polite" class="hidden">
|
||||
{{> mod_lti/cartridge_registration_form }}
|
||||
</div>
|
||||
<div id="external-registration-container" aria-live="polite" class="hidden">
|
||||
{{> mod_lti/external_registration }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tool-list-container" class="loading">
|
||||
{{> mod_lti/tool_list }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['mod_lti/tool_configure_controller'], function(controller) {
|
||||
controller.init();
|
||||
});
|
||||
{{/js}}
|
47
mod/lti/templates/tool_list.mustache
Normal file
47
mod/lti/templates/tool_list.mustache
Normal file
@ -0,0 +1,47 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/tool_list
|
||||
|
||||
This template provides a list of LTI tools.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
}
|
||||
|
||||
}}
|
||||
<h3>{{#str}} tooltypes, mod_lti {{/str}}</h3>
|
||||
<div id="tool-list-loader-container">
|
||||
{{> mod_lti/loader }}
|
||||
</div>
|
||||
{{^tools}}
|
||||
<div id="tool-notools-text" class="container-fluid">{{#str}} no_lti_tools, mod_lti {{/str}}</div>
|
||||
{{/tools}}
|
||||
<div id="tool-card-container" class="container-fluid">
|
||||
{{#tools}}
|
||||
{{> mod_lti/tool_card }}
|
||||
{{/tools}}
|
||||
</div>
|
64
mod/lti/templates/tool_proxy_registration_form.mustache
Normal file
64
mod/lti/templates/tool_proxy_registration_form.mustache
Normal file
@ -0,0 +1,64 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/tool_proxy_registration_form
|
||||
|
||||
This template provides the registration form to submit an external
|
||||
LTI registration.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
}}
|
||||
<div id="tool-proxy-registration-form-container">
|
||||
<div class="registration-loading-container">
|
||||
{{> mod_lti/loader }}
|
||||
<p class="loading-text">{{#str}} loadinghelp, moodle {{/str}}</p>
|
||||
<p id="registration-loading-failed" class="hidden">{{#str}} register_warning, mod_lti {{/str}}</p>
|
||||
</div>
|
||||
<iframe id="registration-page-iframe" name="registration-page-iframe" class="hidden">
|
||||
</iframe>
|
||||
<form action="{{{reg_url}}}" name="ltiLaunchForm" id="ltiLaunchForm" method="post" encType="application/x-www-form-urlencoded" target="registration-page-iframe">
|
||||
<input type="hidden" name="lti_message_type" value="{{lti_message_type}}" />
|
||||
<input type="hidden" name="lti_version" value="{{lti_version}}" />
|
||||
<input type="hidden" name="reg_key" value="{{reg_key}}" />
|
||||
<input type="hidden" name="reg_password" value="{{reg_password}}" />
|
||||
<input type="hidden" name="tc_profile_url" value="{{{tc_profile_url}}}" />
|
||||
<input type="hidden" name="launch_presentation_return_url" value="{{{launch_presentation_return_url}}}" />
|
||||
</form>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery'], function($) {
|
||||
var loadingContainer = $('#tool-proxy-registration-form-container .registration-loading-container');
|
||||
var iframe = $('#registration-page-iframe');
|
||||
var timeout = setTimeout(function () {
|
||||
var failedContainer = $('#registration-loading-failed');
|
||||
failedContainer.removeClass('hidden');
|
||||
}, 20000);
|
||||
|
||||
iframe.load(function() {
|
||||
loadingContainer.addClass('hidden');
|
||||
iframe.removeClass('hidden');
|
||||
});
|
||||
});
|
||||
{{/js}}
|
73
mod/lti/templates/tool_type_capabilities_agree.mustache
Normal file
73
mod/lti/templates/tool_type_capabilities_agree.mustache
Normal file
@ -0,0 +1,73 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_lti/tool_type_capabilities_agree
|
||||
|
||||
List of tool type's capabilities to be agreed to.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
}}
|
||||
<div class="capabilities-container tool-type-{{id}}">
|
||||
<p>{{#str}} capabilitiesrequired, mod_lti {{/str}}</p>
|
||||
<ul>
|
||||
{{#capabilitygroups}}<li>{{.}}</li>{{/capabilitygroups}}
|
||||
</ul>
|
||||
<p>{{#str}} confirmtoolactivation, mod_lti {{/str}}</p>
|
||||
<button class="yes btn btn-success">{{#str}} yes {{/str}}</button>
|
||||
<button class="no btn btn-danger">{{#str}} no {{/str}}</button>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'mod_lti/events', 'mod_lti/keys'], function($, ltiEvents, KEYS) {
|
||||
var container = $('.capabilities-container.tool-type-{{id}}');
|
||||
var yesButton = container.find('button.yes');
|
||||
var noButton = container.find('button.no');
|
||||
|
||||
yesButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
container.trigger(ltiEvents.CAPABILITIES_AGREE);
|
||||
});
|
||||
yesButton.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
yesButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
noButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
container.trigger(ltiEvents.CAPABILITIES_DECLINE);
|
||||
});
|
||||
noButton.keypress(function(e) {
|
||||
if (!e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey) {
|
||||
if (e.keyCode == KEYS.ENTER || e.keyCode == KEYS.SPACE) {
|
||||
e.preventDefault();
|
||||
noButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
{{/js}}
|
@ -1,5 +1,5 @@
|
||||
@mod @mod_lti
|
||||
Feature: Add tool types
|
||||
Feature: Add tools
|
||||
In order to provide activities for learners
|
||||
As a teacher
|
||||
I need to be able to add external tools to a course
|
||||
@ -15,12 +15,12 @@ Feature: Add tool types
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Manage external tool types" node in "Site administration > Plugins > Activity modules > LTI"
|
||||
And I follow "Add external tool configuration"
|
||||
And I navigate to "Manage tools" node in "Site administration > Plugins > Activity modules > LTI"
|
||||
And I follow "Manage preconfigured tools"
|
||||
And I follow "Add preconfigured tool"
|
||||
And I set the following fields to these values:
|
||||
| Tool name | Teaching Tool 1 |
|
||||
| Show tool type when creating tool instances | 1 |
|
||||
And I set the field "Tool base URL" to local url "/mod/lti/tests/fixtures/tool_provider.html"
|
||||
And I set the field "Tool base URL/Cartridge URL" to local url "/mod/lti/tests/fixtures/tool_provider.html"
|
||||
And I press "Save changes"
|
||||
And I log out
|
||||
|
||||
@ -34,4 +34,4 @@ Feature: Add tool types
|
||||
| Launch container | Embed |
|
||||
And I open "Test tool activity 1" actions menu
|
||||
And I follow "Edit settings" in the open menu
|
||||
Then the field "External tool type" matches value "Teaching Tool 1"
|
||||
Then the field "Preconfigured tool" matches value "Teaching Tool 1"
|
||||
|
74
mod/lti/tests/behat/addtype.feature
Normal file
74
mod/lti/tests/behat/addtype.feature
Normal file
@ -0,0 +1,74 @@
|
||||
@mod @mod_lti
|
||||
Feature: Add preconfigured tools via teacher interface
|
||||
In order to provide reusable activities for teachers
|
||||
As a teacher
|
||||
I need to be able to add preconfigured tools
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
|
||||
@javascript
|
||||
Scenario: Add a tool from a cartridge
|
||||
When I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "External tool" to section "1" and I fill the form with:
|
||||
| Activity name | Test tool activity 1 |
|
||||
And I open "Test tool activity 1" actions menu
|
||||
And I follow "Edit settings" in the open menu
|
||||
And I set the field "Launch/Cartridge URL" to local url "/mod/lti/tests/fixtures/ims_cartridge_basic_lti_link.xml"
|
||||
And I press "Save and return to course"
|
||||
And I open "Example tool" actions menu
|
||||
And I follow "Edit settings" in the open menu
|
||||
And I expand all fieldsets
|
||||
Then the field "Launch/Cartridge URL" matches value "http://www.example.com/lti/provider.php"
|
||||
And the field "Secure launch URL" matches value "https://www.example.com/lti/provider.php"
|
||||
And the field "Icon URL" matches value "http://download.moodle.org/unittest/test.jpg"
|
||||
And the field "Secure icon URL" matches value "https://download.moodle.org/unittest/test.jpg"
|
||||
|
||||
@javascript
|
||||
Scenario: Add a preconfigured tool from a cartridge
|
||||
When I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "External tool" to section "1" and I fill the form with:
|
||||
| Activity name | Test tool activity 1 |
|
||||
And I open "Test tool activity 1" actions menu
|
||||
And I follow "Edit settings" in the open menu
|
||||
And I follow "Add preconfigured tool"
|
||||
And I switch to "add_tool" window
|
||||
And I set the field "Tool name" to "Placeholder"
|
||||
And I set the field "Tool base URL/Cartridge URL" to local url "/mod/lti/tests/fixtures/ims_cartridge_basic_lti_link.xml"
|
||||
And I press "Save changes"
|
||||
And I switch to the main window
|
||||
And I wait "2" seconds
|
||||
And I follow "Edit preconfigured tool"
|
||||
And I switch to "edit_tool" window
|
||||
Then the field "Tool base URL/Cartridge URL" matches value "http://www.example.com/lti/provider.php"
|
||||
And the field "Icon URL" matches value "http://download.moodle.org/unittest/test.jpg"
|
||||
And the field "Secure icon URL" matches value "https://download.moodle.org/unittest/test.jpg"
|
||||
And I press "Cancel"
|
||||
And I switch to the main window
|
||||
|
||||
@javascript
|
||||
Scenario: Add and use a preconfigured tool
|
||||
When I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "External tool" to section "1" and I fill the form with:
|
||||
| Activity name | Test tool activity 1 |
|
||||
And I open "Test tool activity 1" actions menu
|
||||
And I follow "Edit settings" in the open menu
|
||||
And I set the field "Launch/Cartridge URL" to local url "/mod/lti/tests/fixtures/tool_provider.html"
|
||||
And I press "Save and return to course"
|
||||
And I follow "Test tool activity 1"
|
||||
And I switch to "contentframe" iframe
|
||||
And I should see "This represents a tool provider"
|
43
mod/lti/tests/behat/toolconfigure.feature
Normal file
43
mod/lti/tests/behat/toolconfigure.feature
Normal file
@ -0,0 +1,43 @@
|
||||
@mod @mod_lti
|
||||
Feature: Configure tool types
|
||||
In order to allow teachers to add LTI tools
|
||||
As an admin
|
||||
I need to be able to add, remove and configure tool types
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
|
||||
| student1 | Sam1 | Student1 | student1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Manage tools" node in "Site administration > Plugins > Activity modules > LTI"
|
||||
|
||||
@javascript
|
||||
Scenario: Add a tool type from a cartridge URL
|
||||
When I set the field "url" to local url "/mod/lti/tests/fixtures/ims_cartridge_basic_lti_link.xml"
|
||||
And I press "Add"
|
||||
Then I should see "Enter your consumer key and shared secret"
|
||||
And I press "Save changes"
|
||||
And I should see "Example tool"
|
||||
|
||||
@javascript
|
||||
Scenario: Try to add a non-existant cartridge
|
||||
When I set the field "url" to local url "/mod/lti/tests/fixtures/nonexistant.xml"
|
||||
And I press "Add"
|
||||
Then I should see "Enter your consumer key and shared secret"
|
||||
And I press "Save changes"
|
||||
And I should see "Unable to create tool"
|
||||
|
||||
@javascript
|
||||
Scenario: Attempt to add a tool type from a configuration URL, then cancel
|
||||
When I set the field "url" to local url "/mod/lti/tests/fixtures/tool_provider.html"
|
||||
And I press "Add"
|
||||
Then I should see "Cancel"
|
||||
And I press "cancel-external-registration"
|
@ -281,4 +281,163 @@ class mod_lti_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test create tool proxy
|
||||
*/
|
||||
public function test_mod_lti_create_tool_proxy() {
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
$this->assertEquals('Test proxy', $proxy->name);
|
||||
$this->assertEquals($this->getExternalTestFileUrl('/test.html'), $proxy->regurl);
|
||||
$this->assertEquals(LTI_TOOL_PROXY_STATE_PENDING, $proxy->state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test create tool proxy with duplicate url
|
||||
*/
|
||||
public function test_mod_lti_create_tool_proxy_duplicateurl() {
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy 1', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy 2', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test create tool proxy without sufficient capability
|
||||
*/
|
||||
public function test_mod_lti_create_tool_proxy_without_capability() {
|
||||
self::setUser($this->teacher);
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test delete tool proxy
|
||||
*/
|
||||
public function test_mod_lti_delete_tool_proxy() {
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
$this->assertNotEmpty(lti_get_tool_proxy($proxy->id));
|
||||
|
||||
$proxy = mod_lti_external::delete_tool_proxy($proxy->id);
|
||||
$this->assertEquals('Test proxy', $proxy->name);
|
||||
$this->assertEquals($this->getExternalTestFileUrl('/test.html'), $proxy->regurl);
|
||||
$this->assertEquals(LTI_TOOL_PROXY_STATE_PENDING, $proxy->state);
|
||||
$this->assertEmpty(lti_get_tool_proxy($proxy->id));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test get tool proxy registration request
|
||||
*/
|
||||
public function test_mod_lti_get_tool_proxy_registration_request() {
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
$request = mod_lti_external::get_tool_proxy_registration_request($proxy->id);
|
||||
$this->assertEquals('ToolProxyRegistrationRequest', $request['lti_message_type']);
|
||||
$this->assertEquals('LTI-2p0', $request['lti_version']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test get tool types
|
||||
*/
|
||||
public function test_mod_lti_get_tool_types() {
|
||||
// Create a tool proxy.
|
||||
$proxy = mod_lti_external::create_tool_proxy('Test proxy', $this->getExternalTestFileUrl('/test.html'), array(), array());
|
||||
|
||||
// Create a tool type, associated with that proxy.
|
||||
$type = new stdClass();
|
||||
$data = new stdClass();
|
||||
$type->state = LTI_TOOL_STATE_CONFIGURED;
|
||||
$type->name = "Test tool";
|
||||
$type->description = "Example description";
|
||||
$type->toolproxyid = $proxy->id;
|
||||
$type->baseurl = $this->getExternalTestFileUrl('/test.html');
|
||||
$typeid = lti_add_type($type, $data);
|
||||
|
||||
$types = mod_lti_external::get_tool_types($proxy->id);
|
||||
$this->assertEquals(1, count($types));
|
||||
$type = $types[0];
|
||||
$this->assertEquals('Test tool', $type['name']);
|
||||
$this->assertEquals('Example description', $type['description']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test create tool type
|
||||
*/
|
||||
public function test_mod_lti_create_tool_type() {
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'), '', '');
|
||||
$this->assertEquals('Example tool', $type['name']);
|
||||
$this->assertEquals('Example tool description', $type['description']);
|
||||
$this->assertEquals($this->getExternalTestFileUrl('/test.jpg', true), $type['urls']['icon']);
|
||||
$typeentry = lti_get_type($type['id']);
|
||||
$this->assertEquals('http://www.example.com/lti/provider.php', $typeentry->baseurl);
|
||||
$config = lti_get_type_config($type['id']);
|
||||
$this->assertTrue(isset($config['sendname']));
|
||||
$this->assertTrue(isset($config['sendemailaddr']));
|
||||
$this->assertTrue(isset($config['acceptgrades']));
|
||||
$this->assertTrue(isset($config['forcessl']));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test create tool type failure from non existant file
|
||||
*/
|
||||
public function test_mod_lti_create_tool_type_nonexistant_file() {
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/doesntexist.xml'), '', '');
|
||||
}
|
||||
|
||||
/*
|
||||
* Test create tool type failure from xml that is not a cartridge
|
||||
*/
|
||||
public function test_mod_lti_create_tool_type_bad_file() {
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/rsstest.xml'), '', '');
|
||||
}
|
||||
|
||||
/*
|
||||
* Test creating of tool types without sufficient capability
|
||||
*/
|
||||
public function test_mod_lti_create_tool_type_without_capability() {
|
||||
self::setUser($this->teacher);
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'), '', '');
|
||||
}
|
||||
|
||||
/*
|
||||
* Test update tool type
|
||||
*/
|
||||
public function test_mod_lti_update_tool_type() {
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'), '', '');
|
||||
$type = mod_lti_external::update_tool_type($type['id'], 'New name', 'New description', LTI_TOOL_STATE_PENDING);
|
||||
$this->assertEquals('New name', $type['name']);
|
||||
$this->assertEquals('New description', $type['description']);
|
||||
$this->assertEquals('Pending', $type['state']['text']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test delete tool type
|
||||
*/
|
||||
public function test_mod_lti_delete_tool_type() {
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'), '', '');
|
||||
$this->assertNotEmpty(lti_get_type($type['id']));
|
||||
$type = mod_lti_external::delete_tool_type($type['id']);
|
||||
$this->assertEmpty(lti_get_type($type['id']));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test delete tool type without sufficient capability
|
||||
*/
|
||||
public function test_mod_lti_delete_tool_type_without_capability() {
|
||||
$type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'), '', '');
|
||||
$this->assertNotEmpty(lti_get_type($type['id']));
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
self::setUser($this->teacher);
|
||||
$type = mod_lti_external::delete_tool_type($type['id']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test is cartridge
|
||||
*/
|
||||
public function test_mod_lti_is_cartridge() {
|
||||
$result = mod_lti_external::is_cartridge($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'));
|
||||
$this->assertTrue($result['iscartridge']);
|
||||
$result = mod_lti_external::is_cartridge($this->getExternalTestFileUrl('/test.html'));
|
||||
$this->assertFalse($result['iscartridge']);
|
||||
}
|
||||
}
|
||||
|
28
mod/lti/tests/fixtures/ims_cartridge_basic_lti_link.xml
vendored
Normal file
28
mod/lti/tests/fixtures/ims_cartridge_basic_lti_link.xml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<basic_lti_link xmlns="http://www.imsglobal.org/xsd/imsbasiclti_v1p0"
|
||||
xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0"
|
||||
xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0"
|
||||
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0 imsbasiclti_v1p0p1.xsd
|
||||
http://www.imsglobal.org/xsd/imslticm_v1p0 imslticm_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticp_v1p0 imslticp_v1p0.xsd">
|
||||
<title>Example tool</title>
|
||||
<description>Example tool description</description>
|
||||
<extensions platform="my.lms.com">
|
||||
<lticm:property name="icon_url">http://download.moodle.org/unittest/test.jpg</lticm:property>
|
||||
<lticm:property name="secure_icon_url">https://download.moodle.org/unittest/test.jpg</lticm:property>
|
||||
</extensions>
|
||||
<launch_url>http://www.example.com/lti/provider.php</launch_url>
|
||||
<secure_launch_url>https://www.example.com/lti/provider.php</secure_launch_url>
|
||||
<icon>http://download.moodle.org/unittest/test.jpg</icon>
|
||||
<secure_icon>https://download.moodle.org/unittest/test.jpg</secure_icon>
|
||||
<vendor>
|
||||
<lticp:code>moodle.org</lticp:code>
|
||||
<lticp:name>Moodle</lticp:name>
|
||||
<lticp:description>Moodle Learning Management System Example Cartridge</lticp:description>
|
||||
<lticp:url>http://www.moodle.org/</lticp:url>
|
||||
<lticp:contact>
|
||||
<lticp:email>moodle@example.com</lticp:email>
|
||||
</lticp:contact>
|
||||
</vendor>
|
||||
</basic_lti_link>
|
@ -292,4 +292,37 @@ class mod_lti_locallib_testcase extends advanced_testcase {
|
||||
$this->assertEquals(0, $config->lti_forcessl);
|
||||
$this->assertEquals(0, $type->forcessl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests lti_load_type_from_cartridge and lti_load_type_if_cartridge
|
||||
*/
|
||||
public function test_lti_load_type_from_cartridge() {
|
||||
$type = new stdClass();
|
||||
$type->lti_toolurl = $this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml');
|
||||
|
||||
lti_load_type_if_cartridge($type);
|
||||
|
||||
$this->assertEquals('Example tool', $type->lti_typename);
|
||||
$this->assertEquals('Example tool description', $type->lti_description);
|
||||
$this->assertEquals('http://www.example.com/lti/provider.php', $type->lti_toolurl);
|
||||
$this->assertEquals('http://download.moodle.org/unittest/test.jpg', $type->lti_icon);
|
||||
$this->assertEquals('https://download.moodle.org/unittest/test.jpg', $type->lti_secureicon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests lti_load_tool_from_cartridge and lti_load_tool_if_cartridge
|
||||
*/
|
||||
public function test_lti_load_tool_from_cartridge() {
|
||||
$lti = new stdClass();
|
||||
$lti->toolurl = $this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml');
|
||||
|
||||
lti_load_tool_if_cartridge($lti);
|
||||
|
||||
$this->assertEquals('Example tool', $lti->name);
|
||||
$this->assertEquals('Example tool description', $lti->intro);
|
||||
$this->assertEquals('http://www.example.com/lti/provider.php', $lti->toolurl);
|
||||
$this->assertEquals('https://www.example.com/lti/provider.php', $lti->securetoolurl);
|
||||
$this->assertEquals('http://download.moodle.org/unittest/test.jpg', $lti->icon);
|
||||
$this->assertEquals('https://download.moodle.org/unittest/test.jpg', $lti->secureicon);
|
||||
}
|
||||
}
|
||||
|
60
mod/lti/toolconfigure.php
Normal file
60
mod/lti/toolconfigure.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?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 page allows the configuration of external tools that meet the LTI specification.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2015 Ryan Wyllie <ryan@moodle.com>
|
||||
* @author Ryan Wyllie
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
|
||||
$cartridgeurl = optional_param('cartridgeurl', '', PARAM_URL);
|
||||
|
||||
// No guest autologin.
|
||||
require_login(0, false);
|
||||
admin_externalpage_setup('ltitoolconfigure');
|
||||
|
||||
if ($cartridgeurl) {
|
||||
$type = new stdClass();
|
||||
$data = new stdClass();
|
||||
$type->state = LTI_TOOL_STATE_CONFIGURED;
|
||||
$data->lti_coursevisible = 1;
|
||||
lti_load_type_from_cartridge($cartridgeurl, $data);
|
||||
lti_add_type($type, $data);
|
||||
}
|
||||
|
||||
$pageurl = new moodle_url('/mod/lti/toolconfigure.php');
|
||||
$PAGE->set_url($pageurl);
|
||||
$PAGE->set_title("{$SITE->shortname}: " . get_string('toolregistration', 'mod_lti'));
|
||||
$PAGE->requires->string_for_js('success', 'moodle');
|
||||
$PAGE->requires->string_for_js('error', 'moodle');
|
||||
$PAGE->requires->string_for_js('successfullycreatedtooltype', 'mod_lti');
|
||||
$PAGE->requires->string_for_js('failedtocreatetooltype', 'mod_lti');
|
||||
$output = $PAGE->get_renderer('mod_lti');
|
||||
|
||||
echo $output->header();
|
||||
|
||||
$page = new \mod_lti\output\tool_configure_page();
|
||||
echo $output->render($page);
|
||||
|
||||
echo $output->footer();
|
@ -34,6 +34,11 @@ require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
$action = optional_param('action', '', PARAM_ALPHANUMEXT);
|
||||
$id = optional_param('id', '', PARAM_INT);
|
||||
$tab = optional_param('tab', '', PARAM_ALPHAEXT);
|
||||
$returnto = optional_param('returnto', '', PARAM_ALPHANUM);
|
||||
|
||||
if ($returnto == 'toolconfigure') {
|
||||
$returnurl = new moodle_url($CFG->wwwroot . '/mod/lti/toolconfigure.php');
|
||||
}
|
||||
|
||||
// No guest autologin.
|
||||
require_login(0, false);
|
||||
@ -47,8 +52,11 @@ if (!$err) {
|
||||
$err = empty($type->toolproxyid);
|
||||
}
|
||||
if ($err) {
|
||||
$redirect = new moodle_url('/mod/lti/typessettings.php',
|
||||
array('action' => $action, 'id' => $id, 'sesskey' => sesskey(), 'tab' => $tab));
|
||||
$params = array('action' => $action, 'id' => $id, 'sesskey' => sesskey(), 'tab' => $tab);
|
||||
if (!empty($returnto)) {
|
||||
$params['returnto'] = $returnto;
|
||||
}
|
||||
$redirect = new moodle_url('/mod/lti/typessettings.php', $params);
|
||||
redirect($redirect);
|
||||
}
|
||||
|
||||
@ -56,11 +64,17 @@ $pageurl = new moodle_url('/mod/lti/toolssettings.php');
|
||||
if (!empty($id)) {
|
||||
$pageurl->param('id', $id);
|
||||
}
|
||||
if (!empty($returnto)) {
|
||||
$pageurl->param('returnto', $returnto);
|
||||
}
|
||||
$PAGE->set_url($pageurl);
|
||||
|
||||
admin_externalpage_setup('managemodules'); // Hacky solution for printing the admin page.
|
||||
|
||||
$redirect = "$CFG->wwwroot/$CFG->admin/settings.php?section=modsettinglti&tab={$tab}";
|
||||
if (!empty($returnurl)) {
|
||||
$redirect = $returnurl;
|
||||
}
|
||||
|
||||
if ($action == 'accept') {
|
||||
lti_set_state_for_type($id, LTI_TOOL_STATE_CONFIGURED);
|
||||
|
@ -56,6 +56,11 @@ require_once($CFG->dirroot.'/mod/lti/locallib.php');
|
||||
$action = optional_param('action', null, PARAM_ALPHANUMEXT);
|
||||
$id = optional_param('id', null, PARAM_INT);
|
||||
$tab = optional_param('tab', '', PARAM_ALPHAEXT);
|
||||
$returnto = optional_param('returnto', '', PARAM_ALPHANUM);
|
||||
|
||||
if ($returnto == 'toolconfigure') {
|
||||
$returnurl = new moodle_url($CFG->wwwroot . '/mod/lti/toolconfigure.php');
|
||||
}
|
||||
|
||||
// No guest autologin.
|
||||
require_login(0, false);
|
||||
@ -67,8 +72,11 @@ if (!empty($id)) {
|
||||
$type = lti_get_type_type_config($id);
|
||||
if (!empty($type->toolproxyid)) {
|
||||
$sesskey = required_param('sesskey', PARAM_RAW);
|
||||
$redirect = new moodle_url('/mod/lti/toolssettings.php',
|
||||
array('action' => $action, 'id' => $id, 'sesskey' => $sesskey, 'tab' => $tab));
|
||||
$params = array('action' => $action, 'id' => $id, 'sesskey' => $sesskey, 'tab' => $tab);
|
||||
if (!empty($returnto)) {
|
||||
$params['returnto'] = $returnto;
|
||||
}
|
||||
$redirect = new moodle_url('/mod/lti/toolssettings.php', $params);
|
||||
redirect($redirect);
|
||||
}
|
||||
} else {
|
||||
@ -82,11 +90,17 @@ $pageurl = new moodle_url('/mod/lti/typessettings.php');
|
||||
if (!empty($id)) {
|
||||
$pageurl->param('id', $id);
|
||||
}
|
||||
if (!empty($returnto)) {
|
||||
$pageurl->param('returnto', $returnto);
|
||||
}
|
||||
$PAGE->set_url($pageurl);
|
||||
|
||||
admin_externalpage_setup('managemodules'); // Hacky solution for printing the admin page.
|
||||
|
||||
$redirect = "$CFG->wwwroot/$CFG->admin/settings.php?section=modsettinglti&tab={$tab}";
|
||||
if (!empty($returnurl)) {
|
||||
$redirect = $returnurl;
|
||||
}
|
||||
|
||||
if ($action == 'accept') {
|
||||
lti_set_state_for_type($id, LTI_TOOL_STATE_CONFIGURED);
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2015111601; // The current module version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2016041800; // The current module version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2015111000; // Requires this Moodle version.
|
||||
$plugin->component = 'mod_lti'; // Full name of the plugin (used for diagnostics).
|
||||
$plugin->cron = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user