Fixing issues with launching a tool which is not configured in the admin side, and...
authorChris Scribner <scriby@gmail.com>
Thu, 1 Sep 2011 17:22:08 +0000 (13:22 -0400)
committerChris Scribner <scriby@gmail.com>
Mon, 7 Nov 2011 01:41:47 +0000 (20:41 -0500)
mod/lti/db/install.xml
mod/lti/locallib.php
mod/lti/view.php

index 14e77cc..f606a69 100644 (file)
@@ -1,5 +1,5 @@
 <?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"/>
@@ -42,7 +45,7 @@
         <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"/>
index 2a4801c..e0fc4ae 100644 (file)
@@ -60,26 +60,47 @@ define('LTI_TOOL_STATE_CONFIGURED', 1);
 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
@@ -104,8 +125,6 @@ function lti_view($instance, $makeobject=false) {
     \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
@@ -303,10 +322,42 @@ function lti_get_type_config($typeid) {
     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
@@ -341,29 +392,42 @@ function lti_get_domain_from_url($url){
     }\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
@@ -377,6 +441,11 @@ function lti_get_best_tool_by_url($url, $tools){
         \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
index 3656833..1a1a533 100644 (file)
@@ -78,7 +78,11 @@ if ($id) {
 }\r
 \r
 $tool = lti_get_tool_by_url_match($basiclti->toolurl);\r
-$toolconfig = lti_get_type_config($tool->id);\r
+if($tool){\r
+    $toolconfig = lti_get_type_config($tool->id);\r
+} else {\r
+    $toolconfig = array('launchcontainer' => LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS);\r
+}\r
 \r
 $PAGE->set_cm($cm, $course); // set's up global $COURSE\r
 $context = get_context_instance(CONTEXT_MODULE, $cm->id);\r