<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/lti/db" VERSION="20110829" COMMENT="XMLDB file for Moodle mod/lti"
+<XMLDB PATH="mod/lti/db" VERSION="20110901" COMMENT="XMLDB file for Moodle mod/lti"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<FIELD NAME="instructorcustomparameters" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="Additional custom parameters provided by the instructor" PREVIOUS="instructorchoiceallowsetting" NEXT="instructorchoiceacceptgrades"/>
<FIELD NAME="instructorchoiceacceptgrades" TYPE="int" LENGTH="1" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="Accept grades from tool" PREVIOUS="instructorcustomparameters" NEXT="grade"/>
<FIELD NAME="grade" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="100" SEQUENCE="false" DECIMALS="5" COMMENT="Grade scale" PREVIOUS="instructorchoiceacceptgrades" NEXT="launchcontainer"/>
- <FIELD NAME="launchcontainer" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" COMMENT="Launch external tool in a pop-up" PREVIOUS="grade" NEXT="debuglaunch"/>
- <FIELD NAME="debuglaunch" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Enable the debug-style launch which pauses before auto-submit" PREVIOUS="launchcontainer" NEXT="showtitle"/>
+ <FIELD NAME="launchcontainer" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" COMMENT="Launch external tool in a pop-up" PREVIOUS="grade" NEXT="resourcekey"/>
+ <FIELD NAME="resourcekey" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="launchcontainer" NEXT="password"/>
+ <FIELD NAME="password" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" PREVIOUS="resourcekey" NEXT="debuglaunch"/>
+ <FIELD NAME="debuglaunch" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Enable the debug-style launch which pauses before auto-submit" PREVIOUS="password" NEXT="showtitle"/>
<FIELD NAME="showtitle" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="debuglaunch" NEXT="showdescription"/>
- <FIELD NAME="showdescription" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="showtitle"/>
+ <FIELD NAME="showdescription" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="showtitle" NEXT="servicesalt"/>
+ <FIELD NAME="servicesalt" TYPE="char" LENGTH="40" NOTNULL="false" SEQUENCE="false" PREVIOUS="showdescription"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<FIELD NAME="tooldomain" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="baseurl" NEXT="state"/>
<FIELD NAME="state" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="2" SEQUENCE="false" COMMENT="Active = 1, Pending = 2, Rejected = 3" PREVIOUS="tooldomain" NEXT="course"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="state" NEXT="coursevisible"/>
- <FIELD NAME="coursevisible" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" DEFAULT="0" PREVIOUS="course" NEXT="createdby"/>
+ <FIELD NAME="coursevisible" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="course" NEXT="createdby"/>
<FIELD NAME="createdby" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="coursevisible" NEXT="timecreated"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="createdby" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="timecreated"/>
define('LTI_TOOL_STATE_PENDING', 2);\r
define('LTI_TOOL_STATE_REJECTED', 3);\r
\r
+define('LTI_SETTING_NEVER', 0);\r
+define('LTI_SETTING_ALWAYS', 1);\r
+define('LTI_SETTING_DEFAULT', 2);\r
+\r
/**\r
* Prints a Basic LTI activity\r
*\r
* $param int $basicltiid Basic LTI activity id\r
*/\r
function lti_view($instance, $makeobject=false) {\r
- global $PAGE;\r
+ global $PAGE, $CFG;\r
\r
if(empty($instance->typeid)){\r
$tool = lti_get_tool_by_url_match($instance->toolurl);\r
if($tool){\r
$typeid = $tool->id;\r
} else {\r
- //Tool not found\r
+ $typeid = null;\r
}\r
} else {\r
$typeid = $instance->typeid;\r
}\r
\r
- $typeconfig = lti_get_type_config($typeid);\r
+ if($typeid){\r
+ $typeconfig = lti_get_type_config($typeid);\r
+ } else {\r
+ //There is no admin configuration for this tool. Use configuration in the lti instance record plus some defaults.\r
+ $typeconfig = (array)$instance;\r
+ \r
+ $typeconfig['sendname'] = $instance->instructorchoicesendname;\r
+ $typeconfig['sendemailaddr'] = $instance->instructorchoicesendemailaddr;\r
+ $typeconfig['customparameters'] = $instance->instructorcustomparameters;\r
+ }\r
+ \r
+ //Default the organizationid if not specified\r
+ if(empty($typeconfig['organizationid'])){\r
+ $urlparts = parse_url($CFG->wwwroot);\r
+ \r
+ $typeconfig['organizationid'] = $urlparts['host'];\r
+ }\r
+ \r
$endpoint = !empty($instance->toolurl) ? $instance->toolurl : $typeconfig['toolurl'];\r
$key = !empty($instance->resourcekey) ? $instance->resourcekey : $typeconfig['resourcekey'];\r
$secret = !empty($instance->password) ? $instance->password : $typeconfig['password'];\r
\r
$content = post_launch_html($parms, $endpoint, $debuglaunch);\r
\r
-// $cm = get_coursemodule_from_instance("lti", $instance->id);\r
-// print '<object height='.$height.' width="80%" data="launch.php?id='.$cm->id.'">'.$content.'</object>';\r
echo $content;\r
}\r
\r
return $typeconfig;\r
}\r
\r
-function lti_get_tools_by_domain($domain){\r
- global $DB;\r
+function lti_get_tools_by_url($url, $state){\r
+ $domain = lti_get_domain_from_url($url);\r
\r
- return $DB->get_records('lti_types', array('tooldomain' => $domain, 'state' => LTI_TOOL_STATE_CONFIGURED));\r
+ return lti_get_tools_by_domain($domain, $state);\r
+}\r
+\r
+function lti_get_tools_by_domain($domain, $state = null, $courseid = null){\r
+ global $DB, $SITE;\r
+ \r
+ $filters = array('tooldomain' => $domain);\r
+ \r
+ $statefilter = '';\r
+ $coursefilter = '';\r
+ \r
+ if($state){\r
+ $statefilter = 'AND state = :state';\r
+ }\r
+ \r
+ if($courseid && $courseid != $SITE->id){\r
+ $coursefilter = 'OR course = :courseid';\r
+ }\r
+ \r
+ $query = <<<QUERY\r
+ SELECT * FROM {lti_types}\r
+ WHERE\r
+ tooldomain = :tooldomain\r
+ AND (course = :siteid $coursefilter)\r
+ $statefilter\r
+QUERY;\r
+ \r
+ return $DB->get_records_sql($query, array(\r
+ 'courseid' => $courseid, \r
+ 'siteid' => $SITE->id, \r
+ 'tooldomain' => $domain, \r
+ 'state' => $state\r
+ ));\r
}\r
\r
/**\r
}\r
}\r
\r
-function lti_get_tool_by_url_match($url){\r
- $domain = lti_get_domain_from_url($url);\r
- \r
- $possibletools = lti_get_tools_by_domain($domain);\r
+function lti_get_tool_by_url_match($url, $courseid = null){\r
+ $possibletools = lti_get_tools_by_url($url, LTI_TOOL_STATE_CONFIGURED, $courseid);\r
\r
return lti_get_best_tool_by_url($url, $possibletools);\r
}\r
\r
+function lti_get_url_thumbprint($url){\r
+ $urlparts = parse_url(strtolower($url));\r
+ if(!isset($urlparts['path'])){\r
+ $urlparts['path'] = '';\r
+ }\r
+ \r
+ if(substr($urlparts['host'], 0, 3) === 'www'){\r
+ $urllparts['host'] = substr(3);\r
+ }\r
+ \r
+ return $urllower = $urlparts['host'] . '/' . $urlparts['path'];\r
+}\r
+\r
function lti_get_best_tool_by_url($url, $tools){\r
if(count($tools) === 0){\r
return null;\r
}\r
\r
- $urllower = strtolower($url);\r
+ $urllower = lti_get_url_thumbprint($url);\r
\r
foreach($tools as $tool){\r
$tool->_matchscore = 0;\r
- \r
- $toolbaseurllower = strtolower($tool->baseurl);\r
+ \r
+ $toolbaseurllower = lti_get_url_thumbprint($tool->baseurl);\r
\r
if($urllower === $toolbaseurllower){\r
+ //100 points for exact match\r
$tool->_matchscore += 100;\r
- } else if(strstr($urllower, $toolbaseurllower) >= 0){\r
+ } else if(substr($urllower, 0, strlen($toolbaseurllower)) === $toolbaseurllower){\r
+ //50 points if it starts with the base URL\r
$tool->_matchscore += 50;\r
}\r
}\r
\r
}, (object)array('_matchscore' => -1));\r
\r
+ //None of the tools are suitable for this URL\r
+ if($bestmatch->_matchscore <= 0){\r
+ return null;\r
+ }\r
+ \r
return $bestmatch;\r
}\r
\r