mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-54680 enrol_lti: Offer cartridges in LTI provider
This commit is contained in:
parent
6f302b17b9
commit
3e9ab40361
61
enrol/lti/cartridge.php
Normal file
61
enrol/lti/cartridge.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/>.
|
||||
|
||||
/**
|
||||
* Generates an XML IMS Cartridge with the details for the given tool
|
||||
*
|
||||
* @package enrol_lti
|
||||
* @copyright 2016 John Okely <john@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../config.php');
|
||||
require_once($CFG->dirroot . '/lib/weblib.php');
|
||||
|
||||
$toolid = null;
|
||||
$token = null;
|
||||
|
||||
$filearguments = get_file_argument();
|
||||
$arguments = explode('/', trim($filearguments, '/'));
|
||||
if (count($arguments) >= 2) { // Can put cartridge.xml at the end, or anything really.
|
||||
list($toolid, $token) = $arguments;
|
||||
}
|
||||
|
||||
$toolid = optional_param('id', $toolid, PARAM_INT);
|
||||
$token = optional_param('token', $token, PARAM_ALPHANUM);
|
||||
|
||||
// Only show the cartridge if the token parameter is correct.
|
||||
// If we do not compare with a shared secret, someone could very easily
|
||||
// guess an id for the enrolment.
|
||||
if (!\enrol_lti\helper::verify_tool_token($toolid, $token)) {
|
||||
throw new \moodle_exception('incorrecttoken', 'enrol_lti');
|
||||
}
|
||||
|
||||
$tool = \enrol_lti\helper::get_lti_tool($toolid);
|
||||
|
||||
if (!is_enabled_auth('lti')) {
|
||||
print_error('pluginnotenabled', 'auth', '', get_string('pluginname', 'auth_lti'));
|
||||
|
||||
} else if (!enrol_is_enabled('lti')) {
|
||||
print_error('enrolisdisabled', 'enrol_lti');
|
||||
|
||||
} else if ($tool->status != ENROL_INSTANCE_ENABLED) {
|
||||
print_error('enrolisdisabled', 'enrol_lti');
|
||||
|
||||
} else {
|
||||
header('Content-Type: text/xml; charset=utf-8');
|
||||
echo \enrol_lti\helper::create_cartridge($toolid);
|
||||
}
|
@ -380,4 +380,219 @@ class helper {
|
||||
</imsx_POXBody>
|
||||
</imsx_POXEnvelopeRequest>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url to launch the lti tool.
|
||||
*
|
||||
* @param int $toolid the id of the shared tool
|
||||
* @return moodle_url the url to launch the tool
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function get_launch_url($toolid) {
|
||||
return new \moodle_url('/enrol/lti/tool.php', array('id' => $toolid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the lti enrolment instance, or the name of the course/module being shared.
|
||||
*
|
||||
* @param stdClass $tool The lti tool
|
||||
* @return string The name of the tool
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function get_name($tool) {
|
||||
$name = null;
|
||||
|
||||
if (empty($tool->name)) {
|
||||
$toolcontext = \context::instance_by_id($tool->contextid);
|
||||
$name = $toolcontext->get_context_name();
|
||||
} else {
|
||||
$name = $tool->name;
|
||||
};
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description of the course or module that this lti instance points to.
|
||||
*
|
||||
* @param stdClass $tool The lti tool
|
||||
* @return string A description of the tool
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function get_description($tool) {
|
||||
global $DB;
|
||||
$description = '';
|
||||
$context = \context::instance_by_id($tool->contextid);
|
||||
if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$course = $DB->get_record('course', array('id' => $context->instanceid));
|
||||
$description = $course->summary;
|
||||
} else if ($context->contextlevel == CONTEXT_MODULE) {
|
||||
$cmid = $context->instanceid;
|
||||
$cm = get_coursemodule_from_id(false, $context->instanceid, 0, false, MUST_EXIST);
|
||||
$module = $DB->get_record($cm->modname, array('id' => $cm->instance));
|
||||
$description = $module->intro;
|
||||
}
|
||||
return trim(html_to_text($description));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url to the cartridge representing the tool.
|
||||
*
|
||||
* If you have slash arguments enabled, this will be a nice url ending in cartridge.xml.
|
||||
* If not it will be a php page with some parameters passed.
|
||||
*
|
||||
* @param stdClass $tool The lti tool
|
||||
* @return string The url to the cartridge representing the tool
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function get_cartridge_url($tool) {
|
||||
global $CFG;
|
||||
$url = null;
|
||||
|
||||
$id = $tool->id;
|
||||
$token = self::generate_tool_token($tool->id);
|
||||
if ($CFG->slasharguments) {
|
||||
$url = new \moodle_url('/enrol/lti/cartridge.php/' . $id . '/' . $token . '/cartridge.xml');
|
||||
} else {
|
||||
$url = new \moodle_url('/enrol/lti/cartridge.php',
|
||||
array(
|
||||
'id' => $id,
|
||||
'token' => $token
|
||||
)
|
||||
);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique hash for this site and this enrolment instance.
|
||||
*
|
||||
* Used to verify that the link to the cartridge has not just been guessed.
|
||||
*
|
||||
* @param int $toolid The id of the shared tool
|
||||
* @return string MD5 hash of combined site ID and enrolment instance ID.
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function generate_tool_token($toolid) {
|
||||
$siteidentifier = get_site_identifier();
|
||||
$checkhash = md5($siteidentifier . '_enrol_lti_' . $toolid);
|
||||
return $checkhash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the given token matches the token of the given shared tool.
|
||||
*
|
||||
* @param int $toolid The id of the shared tool
|
||||
* @param string $token hash for this site and this enrolment instance
|
||||
* @return boolean True if the token matches, false if it does not
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function verify_tool_token($toolid, $token) {
|
||||
return $token == self::generate_tool_token($toolid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameters of the cartridge as an associative array of partial xpath.
|
||||
*
|
||||
* @param int $toolid The id of the shared tool
|
||||
* @return array Recursive associative array with partial xpath to be concatenated into an xpath expression
|
||||
* before setting the value.
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
protected static function get_cartridge_parameters($toolid) {
|
||||
global $OUTPUT, $PAGE, $SITE;
|
||||
$PAGE->set_context(\context_system::instance());
|
||||
|
||||
// Get the tool.
|
||||
$tool = self::get_lti_tool($toolid);
|
||||
|
||||
// Work out the name of the tool.
|
||||
$title = self::get_name($tool);
|
||||
$launchurl = self::get_launch_url($toolid);
|
||||
$launchurl = $launchurl->out();
|
||||
$icon = $OUTPUT->favicon();
|
||||
$icon = $icon->out();
|
||||
$securelaunchurl = null;
|
||||
$secureicon = null;
|
||||
$vendorurl = new \moodle_url('/');
|
||||
$vendorurl = $vendorurl->out();
|
||||
$description = self::get_description($tool);
|
||||
|
||||
// If we are a https site, we can add the launch url and icon urls as secure equivalents.
|
||||
if (\is_https()) {
|
||||
$securelaunchurl = $launchurl;
|
||||
$secureicon = $icon;
|
||||
}
|
||||
|
||||
return array(
|
||||
"/cc:cartridge_basiclti_link" => array(
|
||||
"/blti:title" => $title,
|
||||
"/blti:description" => $description,
|
||||
"/blti:extensions" => array(
|
||||
"/lticm:property[@name='icon_url']" => $icon,
|
||||
"/lticm:property[@name='secure_icon_url']" => $secureicon
|
||||
),
|
||||
"/blti:launch_url" => $launchurl,
|
||||
"/blti:secure_launch_url" => $securelaunchurl,
|
||||
"/blti:icon" => $icon,
|
||||
"/blti:secure_icon" => $secureicon,
|
||||
"/blti:vendor" => array(
|
||||
"/lticp:code" => $SITE->shortname,
|
||||
"/lticp:name" => $SITE->fullname,
|
||||
"/lticp:description" => trim(html_to_text($SITE->summary)),
|
||||
"/lticp:url" => $vendorurl
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses a recursive associative array, setting the properties of the corresponding
|
||||
* xpath element.
|
||||
*
|
||||
* @param DOMXPath $xpath The xpath with the xml to modify
|
||||
* @param array $parameters The array of xpaths to search through
|
||||
* @param string $prefix The current xpath prefix (gets longer the deeper into the array you go)
|
||||
* @return void
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
protected static function set_xpath($xpath, $parameters, $prefix = '') {
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
self::set_xpath($xpath, $value, $prefix . $key);
|
||||
} else {
|
||||
$result = @$xpath->query($prefix . $key);
|
||||
if ($result) {
|
||||
$node = $result->item(0);
|
||||
if ($node) {
|
||||
if (is_null($value)) {
|
||||
$node->parentNode->removeChild($node);
|
||||
} else {
|
||||
$node->nodeValue = $value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new \coding_exception('Please check your XPATH and try again.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an IMS cartridge for the tool.
|
||||
*
|
||||
* @param int $toolid The id of the shared tool
|
||||
* @return string representing the generated cartridge
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function create_cartridge($toolid) {
|
||||
$cartridge = new \DOMDocument();
|
||||
$cartridge->load(realpath(__DIR__ . '/../xml/imslticc.xml'));
|
||||
$xpath = new \DOMXpath($cartridge);
|
||||
$xpath->registerNamespace('cc', 'http://www.imsglobal.org/xsd/imslticc_v1p0');
|
||||
$parameters = self::get_cartridge_parameters($toolid);
|
||||
self::set_xpath($xpath, $parameters);
|
||||
|
||||
return $cartridge->saveXML();
|
||||
}
|
||||
}
|
||||
|
@ -96,12 +96,7 @@ class manage_table extends \table_sql {
|
||||
* @return string
|
||||
*/
|
||||
public function col_name($tool) {
|
||||
if (empty($tool->name)) {
|
||||
$toolcontext = \context::instance_by_id($tool->contextid);
|
||||
$name = $toolcontext->get_context_name();
|
||||
} else {
|
||||
$name = $tool->name;
|
||||
};
|
||||
$name = helper::get_name($tool);
|
||||
|
||||
return $this->get_display_text($tool, $name);
|
||||
}
|
||||
@ -113,8 +108,9 @@ class manage_table extends \table_sql {
|
||||
* @return string
|
||||
*/
|
||||
public function col_url($tool) {
|
||||
$url = new \moodle_url('/enrol/lti/tool.php', array('id' => $tool->id));
|
||||
return $this->get_display_text($tool, $url);
|
||||
$url = helper::get_cartridge_url($tool);
|
||||
|
||||
return $this->get_copyable_text($tool, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,7 +120,7 @@ class manage_table extends \table_sql {
|
||||
* @return string
|
||||
*/
|
||||
public function col_secret($tool) {
|
||||
return $this->get_display_text($tool, $tool->secret);
|
||||
return $this->get_copyable_text($tool, $tool->secret);
|
||||
}
|
||||
|
||||
|
||||
@ -215,4 +211,22 @@ class manage_table extends \table_sql {
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns text to display in the columns.
|
||||
*
|
||||
* @param \stdClass $tool the tool
|
||||
* @param string $text the text to alter
|
||||
* @return string
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
protected function get_copyable_text($tool, $text) {
|
||||
global $OUTPUT;
|
||||
$copyable = $OUTPUT->render_from_template('core/copy_box', array('text' => $text));
|
||||
if ($tool->status != ENROL_INSTANCE_ENABLED) {
|
||||
return \html_writer::tag('span', $copyable, array('class' => 'dimmed_text', 'style' => 'overflow: scroll'));
|
||||
}
|
||||
|
||||
return $copyable;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ $string['enrolstartdate_help'] = 'If enabled, users can access from this date on
|
||||
$string['frameembeddingnotenabled'] = 'To access the tool, please follow the link below.';
|
||||
$string['gradesync'] = 'Grade synchronisation';
|
||||
$string['gradesync_help'] = 'Whether grades from the tool are sent to the remote system (LTI consumer).';
|
||||
$string['incorrecttoken'] = 'Token was incorrect please check the URL and try again, or contact the administrator of this tool.';
|
||||
$string['maxenrolled'] = 'Maximum enrolled users';
|
||||
$string['maxenrolled_help'] = 'The maximum number of remote users who can access the tool. If set to zero, the number of enrolled users is unlimited.';
|
||||
$string['maxenrolledreached'] = 'The maximum number of remote users allowed to access the tool has been reached.';
|
||||
|
4
enrol/lti/styles.css
Normal file
4
enrol/lti/styles.css
Normal file
@ -0,0 +1,4 @@
|
||||
.copy_box {
|
||||
width: 100%;
|
||||
max-width: 350px;
|
||||
}
|
9
enrol/lti/tests/fixtures/input.xml
vendored
Normal file
9
enrol/lti/tests/fixtures/input.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<firstnode></firstnode>
|
||||
<parentnode>
|
||||
<childnode></childnode>
|
||||
</parentnode>
|
||||
<ambiguous id="0"></ambiguous>
|
||||
<ambiguous id="1"></ambiguous>
|
||||
</root>
|
9
enrol/lti/tests/fixtures/test_ambiguous_nodes-expected.xml
vendored
Normal file
9
enrol/lti/tests/fixtures/test_ambiguous_nodes-expected.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<firstnode/>
|
||||
<parentnode>
|
||||
<childnode/>
|
||||
</parentnode>
|
||||
<ambiguous id="0"/>
|
||||
<ambiguous id="1">Content 1</ambiguous>
|
||||
</root>
|
9
enrol/lti/tests/fixtures/test_correct_xpath-expected.xml
vendored
Normal file
9
enrol/lti/tests/fixtures/test_correct_xpath-expected.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<firstnode>Content 1</firstnode>
|
||||
<parentnode>
|
||||
<childnode>Content 2</childnode>
|
||||
</parentnode>
|
||||
<ambiguous id="0"/>
|
||||
<ambiguous id="1"/>
|
||||
</root>
|
9
enrol/lti/tests/fixtures/test_missing_node-expected.xml
vendored
Normal file
9
enrol/lti/tests/fixtures/test_missing_node-expected.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<firstnode>Content 1</firstnode>
|
||||
<parentnode>
|
||||
<childnode/>
|
||||
</parentnode>
|
||||
<ambiguous id="0"/>
|
||||
<ambiguous id="1"/>
|
||||
</root>
|
9
enrol/lti/tests/fixtures/test_nodes_removed-expected.xml
vendored
Normal file
9
enrol/lti/tests/fixtures/test_nodes_removed-expected.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
|
||||
<parentnode>
|
||||
|
||||
</parentnode>
|
||||
<ambiguous id="0"/>
|
||||
<ambiguous id="1"/>
|
||||
</root>
|
@ -247,6 +247,233 @@ class enrol_lti_helper_testcase extends advanced_testcase {
|
||||
$this->assertTrue(isset($tools[$tool3->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting the launch url of a tool
|
||||
*/
|
||||
public function test_get_launch_url() {
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$data = new stdClass();
|
||||
$data->courseid = $course1->id;
|
||||
$tool1 = $this->create_tool($data);
|
||||
|
||||
$id = $tool1->id;
|
||||
$launchurl = \enrol_lti\helper::get_launch_url($id);
|
||||
$this->assertEquals('http://www.example.com/moodle/enrol/lti/tool.php?id=' . $id, $launchurl->out());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting the cartridge url of a tool
|
||||
*/
|
||||
public function test_get_cartridge_url() {
|
||||
global $CFG;
|
||||
|
||||
$slasharguments = $CFG->slasharguments;
|
||||
|
||||
$CFG->slasharguments = false;
|
||||
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$data = new stdClass();
|
||||
$data->courseid = $course1->id;
|
||||
$tool1 = $this->create_tool($data);
|
||||
|
||||
$id = $tool1->id;
|
||||
$token = \enrol_lti\helper::generate_tool_token($id);
|
||||
$launchurl = \enrol_lti\helper::get_cartridge_url($tool1);
|
||||
$this->assertEquals('http://www.example.com/moodle/enrol/lti/cartridge.php?id=' . $id . '&token=' . $token,
|
||||
$launchurl->out());
|
||||
|
||||
$CFG->slasharguments = true;
|
||||
|
||||
$launchurl = \enrol_lti\helper::get_cartridge_url($tool1);
|
||||
$this->assertEquals('http://www.example.com/moodle/enrol/lti/cartridge.php/' . $id . '/' . $token . '/cartridge.xml',
|
||||
$launchurl->out());
|
||||
|
||||
$CFG->slasharguments = $slasharguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting the name of a tool
|
||||
*/
|
||||
public function test_get_name() {
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$data = new stdClass();
|
||||
$data->courseid = $course1->id;
|
||||
$tool1 = $this->create_tool($data);
|
||||
|
||||
$name = \enrol_lti\helper::get_name($tool1);
|
||||
$this->assertEquals('Course: Test course 1', $name);
|
||||
|
||||
$tool1->name = 'Shared course';
|
||||
$name = \enrol_lti\helper::get_name($tool1);
|
||||
$this->assertEquals('Shared course', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting the description of a tool
|
||||
*/
|
||||
public function test_get_description() {
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$data = new stdClass();
|
||||
$data->courseid = $course1->id;
|
||||
$tool1 = $this->create_tool($data);
|
||||
|
||||
$description = \enrol_lti\helper::get_description($tool1);
|
||||
$this->assertContains('Test course 1 Lorem ipsum dolor sit amet', $description);
|
||||
|
||||
$module1 = $this->getDataGenerator()->create_module('assign', array(
|
||||
'course' => $course1->id
|
||||
));
|
||||
$data = new stdClass();
|
||||
$data->cmid = $module1->cmid;
|
||||
$tool2 = $this->create_tool($data);
|
||||
$description = \enrol_lti\helper::get_description($tool2);
|
||||
$this->assertContains('Test assign 1', $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test verifying a tool token.
|
||||
*/
|
||||
public function test_verify_tool_token() {
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$data = new stdClass();
|
||||
$data->courseid = $course1->id;
|
||||
$tool1 = $this->create_tool($data);
|
||||
|
||||
$token = \enrol_lti\helper::generate_tool_token($tool1->id);
|
||||
$this->assertTrue(\enrol_lti\helper::verify_tool_token($tool1->id, $token));
|
||||
$this->assertFalse(\enrol_lti\helper::verify_tool_token($tool1->id, 'incorrect token!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the set_xpath test
|
||||
*/
|
||||
public function set_xpath_provider() {
|
||||
return [
|
||||
"Correct structure" => [
|
||||
"parameters" => [
|
||||
"/root" => [
|
||||
"/firstnode" => "Content 1",
|
||||
"/parentnode" => [
|
||||
"/childnode" => "Content 2"
|
||||
]
|
||||
]
|
||||
],
|
||||
"expected" => "test_correct_xpath-expected.xml"
|
||||
],
|
||||
"A null value, but no node to remove" => [
|
||||
"parameters" => [
|
||||
"/root" => [
|
||||
"/nonexistant" => null,
|
||||
"/firstnode" => "Content 1"
|
||||
]
|
||||
],
|
||||
"expected" => "test_missing_node-expected.xml"
|
||||
],
|
||||
"A string value, but no node existing to set" => [
|
||||
"parameters" => [
|
||||
"/root" => [
|
||||
"/nonexistant" => "This will not be set",
|
||||
"/firstnode" => "Content 1"
|
||||
]
|
||||
],
|
||||
"expected" => "test_missing_node-expected.xml"
|
||||
],
|
||||
"Array but no children exist" => [
|
||||
"parameters" => [
|
||||
"/root" => [
|
||||
"/nonexistant" => [
|
||||
"/alsononexistant" => "This will not be set"
|
||||
],
|
||||
"/firstnode" => "Content 1"
|
||||
]
|
||||
],
|
||||
"expected" => "test_missing_node-expected.xml"
|
||||
],
|
||||
"Remove nodes" => [
|
||||
"parameters" => [
|
||||
"/root" => [
|
||||
"/parentnode" => [
|
||||
"/childnode" => null
|
||||
],
|
||||
"/firstnode" => null
|
||||
]
|
||||
],
|
||||
"expected" => "test_nodes_removed-expected.xml"
|
||||
],
|
||||
"Get by attribute" => [
|
||||
"parameters" => [
|
||||
"/root" => [
|
||||
"/ambiguous[@id='1']" => 'Content 1'
|
||||
]
|
||||
],
|
||||
"expected" => "test_ambiguous_nodes-expected.xml"
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set_xpath.
|
||||
* @dataProvider set_xpath_provider
|
||||
* @param array $parameters A hash of parameters represented by a heirarchy of xpath expressions
|
||||
* @param string $expected The name of the fixture file containing the expected result.
|
||||
*/
|
||||
public function test_set_xpath($parameters, $expected) {
|
||||
$helper = new ReflectionClass('enrol_lti\\helper');
|
||||
$function = $helper->getMethod('set_xpath');
|
||||
$function->setAccessible(true);
|
||||
|
||||
$document = new \DOMDocument();
|
||||
$document->load(realpath(__DIR__ . '/fixtures/input.xml'));
|
||||
$xpath = new \DOMXpath($document);
|
||||
$function->invokeArgs(null, [$xpath, $parameters]);
|
||||
$result = $document->saveXML();
|
||||
$expected = file_get_contents(realpath(__DIR__ . '/fixtures/' . $expected));
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set_xpath when an incorrect xpath expression is given.
|
||||
* @expectedException coding_exception
|
||||
*/
|
||||
public function test_set_xpath_incorrect_xpath() {
|
||||
$parameters = [
|
||||
"/root" => [
|
||||
"/firstnode" => null,
|
||||
"/parentnode*&#^*#(" => [
|
||||
"/childnode" => null
|
||||
],
|
||||
]
|
||||
];
|
||||
$helper = new ReflectionClass('enrol_lti\\helper');
|
||||
$function = $helper->getMethod('set_xpath');
|
||||
$function->setAccessible(true);
|
||||
|
||||
$document = new \DOMDocument();
|
||||
$document->load(realpath(__DIR__ . '/fixtures/input.xml'));
|
||||
$xpath = new \DOMXpath($document);
|
||||
$function->invokeArgs(null, [$xpath, $parameters]);
|
||||
$result = $document->saveXML();
|
||||
$expected = file_get_contents(realpath(__DIR__ . '/fixtures/' . $expected));
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create cartridge.
|
||||
*/
|
||||
public function test_create_cartridge() {
|
||||
global $CFG;
|
||||
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$data = new stdClass();
|
||||
$data->courseid = $course1->id;
|
||||
$tool1 = $this->create_tool($data);
|
||||
|
||||
$cartridge = \enrol_lti\helper::create_cartridge($tool1->id);
|
||||
$this->assertContains('<blti:title>Test LTI</blti:title>', $cartridge);
|
||||
$this->assertContains("<blti:icon>$CFG->wwwroot/theme/image.php/_s/clean/theme/1/favicon</blti:icon>", $cartridge);
|
||||
$this->assertContains("<blti:launch_url>$CFG->wwwroot/enrol/lti/tool.php?id=$tool1->id</blti:launch_url>", $cartridge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function used to create a tool.
|
||||
*
|
||||
@ -267,6 +494,12 @@ class enrol_lti_helper_testcase extends advanced_testcase {
|
||||
$course = get_course($data->courseid);
|
||||
}
|
||||
|
||||
if (!empty($data->cmid)) {
|
||||
$data->contextid = context_module::instance($data->cmid)->id;
|
||||
} else {
|
||||
$data->contextid = context_course::instance($data->courseid)->id;
|
||||
}
|
||||
|
||||
// Set it to enabled if no status was specified.
|
||||
if (!isset($data->status)) {
|
||||
$data->status = ENROL_INSTANCE_ENABLED;
|
||||
@ -274,7 +507,6 @@ class enrol_lti_helper_testcase extends advanced_testcase {
|
||||
|
||||
// Add some extra necessary fields to the data.
|
||||
$data->name = 'Test LTI';
|
||||
$data->contextid = context_course::instance($data->courseid)->id;
|
||||
$data->roleinstructor = $studentrole->id;
|
||||
$data->rolelearner = $teacherrole->id;
|
||||
|
||||
|
@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2016052300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2016052301; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2016051900; // Requires this Moodle version (3.1)
|
||||
$plugin->component = 'enrol_lti'; // Full name of the plugin (used for diagnostics).
|
||||
|
28
enrol/lti/xml/imslticc.xml
Normal file
28
enrol/lti/xml/imslticc.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"
|
||||
xmlns:blti = "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/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd
|
||||
http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd">
|
||||
<blti:title></blti:title>
|
||||
<blti:description></blti:description>
|
||||
<blti:extensions platform="org.moodle.lms">
|
||||
<lticm:property name="icon_url"></lticm:property>
|
||||
<lticm:property name="secure_icon_url"></lticm:property>
|
||||
</blti:extensions>
|
||||
<blti:launch_url></blti:launch_url>
|
||||
<blti:secure_launch_url></blti:secure_launch_url>
|
||||
<blti:icon></blti:icon>
|
||||
<blti:secure_icon></blti:secure_icon>
|
||||
<blti:vendor>
|
||||
<lticp:code></lticp:code>
|
||||
<lticp:name></lticp:name>
|
||||
<lticp:description></lticp:description>
|
||||
<lticp:url></lticp:url>
|
||||
</blti:vendor>
|
||||
<test></test>
|
||||
</cartridge_basiclti_link>
|
41
lib/templates/copy_box.mustache
Normal file
41
lib/templates/copy_box.mustache
Normal file
@ -0,0 +1,41 @@
|
||||
{{!
|
||||
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 core/copy_box
|
||||
|
||||
Interface element to contain text that the user should copy. Will automaticaly select when clicked.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Context variables required for this template:
|
||||
* text The content to be displayed ready for copying
|
||||
|
||||
Example context (json):
|
||||
{ "text": "Copyable text"}
|
||||
}}
|
||||
<input type="text" class="copy_box" value="{{{ text }}}" readonly="readonly" id="copy_box-{{uniqid}}"/>
|
||||
{{# js }}
|
||||
require(['jquery', 'theme_bootstrapbase/bootstrap'], function($) {
|
||||
$('#copy_box-{{uniqid}}').on('click', function() {
|
||||
$(this).select();
|
||||
});
|
||||
});
|
||||
{{/ js }}
|
Loading…
x
Reference in New Issue
Block a user