Overview
This PHP class encapsulates the code required by an LTI-compliant tool producer to communicate with a tool consumer. It provides support for both Basic LTI as well as the versions of "full" LTI as implemented by Blackboard Learn 9 proxy tools and as developed by the EILE project for Moodle 1.9. The class will be updated to support the full IMS Learning Tools Interoperability 2 specification when it is available.
These classes are now replaced by the LTI Tool Provider classes.
System requirements
The LTI Tool Producer class is written for PHP 5.2 (or higher) and MySQL 5.0 (or higher). Other versions may also work but have not been tested.
Installation
PHP source files
The download file available from OSCELOT (see Licence section below) includes the following files:
- LTI_Tool_Producer.php
- LTI_OAuthDataStore.php
The following dependent PHP files are also required:
The LTI_OAuthDataStore.php file only needs to be installed if Basic LTI support is required in which case the following additional dependent PHP file is also required:
All the files should be located in the same directory.
MySQL database tables
The following database tables and relationships should be added to the application database:
consumer_guid VARCHAR(255) NOT NULL,
name VARCHAR(45) NOT NULL,
profile_url VARCHAR(255) NOT NULL,
consumer_name VARCHAR(255) NULL,
consumer_version VARCHAR(255) NULL,
vendor_code VARCHAR(255) NULL,
css_path VARCHAR(255) NULL,
services TEXT NULL,
capabilities TEXT NULL,
enabled BIT NOT NULL,
created DATETIME NOT NULL,
updated DATETIME NOT NULL,
PRIMARY KEY (consumer_guid)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS lti_consumer_instance (
consumer_instance_guid VARCHAR(255) NOT NULL,
consumer_guid VARCHAR(255) NOT NULL,
state VARCHAR(12) NOT NULL,
secret VARCHAR(32) NOT NULL,
created DATETIME NOT NULL,
updated DATETIME NOT NULL,
PRIMARY KEY (consumer_instance_guid)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS lti_nonce (
consumer_instance_guid VARCHAR(255) NOT NULL,
value VARCHAR(32) NOT NULL,
timestamp INT UNSIGNED NOT NULL,
PRIMARY KEY (consumer_instance_guid, value)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE lti_consumer_instance
ADD CONSTRAINT lti_consumer_consumer_instance_FK1 FOREIGN KEY (
consumer_guid)
REFERENCES lti_consumer (
consumer_guid);
ALTER TABLE lti_nonce
ADD CONSTRAINT lti_nonce_consumer_instance_FK1 FOREIGN KEY (
consumer_instance_guid)
REFERENCES lti_consumer_instance (
consumer_instance_guid);
An optional prefix may be added to the table names. For example, if a prefix of "MyApp_" is specified the expected table names would be MyApp_lti_consumer, MyApp_lti_consumer_instance and MyApp_lti_nonce.
Class definitions
The following classes are defined:
- LTI_Category
- LTI_ContentHandler
- LTI_Context
- LTI_Icon
- LTI_Menu
- LTI_SoapClient
- LTI_Tool_Consumer
- LTI_Tool_Consumer_Instance
- LTI_Tool_Info
- LTI_Tool_Producer
- LTI_User
- LTI_Vendor
- LTI_WebService
LTI_Tool_Producer
This is the main working class which handles all communications with the LTI tool consumer. A method handler may be specified for each incoming action to implement any code specific to the tool producer. The following LTI actions are currently supported:
- tool-provision
- bundle
- remove
- config
- state-change
- reregister
- ping
Constructor
function __construct($callbackHandlers, $dbTableNamePrefix = '', $autoEnable = FALSE)
where:
- $callbackHandlers is an associative array containing pairs of action names and callback methods
- $dbTableNamePrefix (optional) is a prefix for the names of database tables
- $autoEnable (optional) will automatically enable the tool consumer when set to true
Methods
- getAction() - get the name of the current action (specified in the query path)
- getSubaction() - get the name of any subaction (remainder of the query path after any "/")
- getLocale() - get the value of the current locale
Properties
- isOK - error status of the current request
- vendor - LTI_Vendor object for the tool producer
- tool_info - LTI_Tool_Info object for the tool producer
- menus - array of LTI_Menu objects for the tool producer
- contentHandlers - array of LTI_ContentHandler objects for the tool producer
- toolWS - array of tool-login LTI_WebService objects required by the tool producer
- ticketWS - array of ticket-login LTI_Vendor objects required by the tool producer
- consumer - LTI_Consumer object for the current request
- consumer_instance - LTI_Consumer_Instance object for the current request
- user - LTI_User object for the current request
- context - LTI_Context object for the current request
- actions - array of names of supported actions
- required_capabilities - array of names of the capabilities required from the tool consumer
Examples
A minimal example for supporting Basic LTI only:
(APP__DB_TABLE_PREFIX is assumed to be a constant which contains the prefix for the application's database table names.)
To include support for "Full" LTI a callback function for at least the 'tool-provision' action is also required:
'bundle' => 'getBundle'), APP__DB_TABLE_PREFIX);
Note that the 'ping', 'config', 'state-change' and 'remove' actions are handled automatically by the class and do not require callback functions to be defined. The 'reregister' function will use the 'tool-provision' callback function.
LTI_Vendor
This class defines details about the vendor (or author) of the tool.
Constructor
function __construct($code, $name, $description, $url, $email)
where:
- $code is a value identifying the vendor of the tool
- $name is the name of the vendor
- $description is a description of the vendor
- $url is a URL to the vendor's website
- $email is an email address for the vendor
Properties
- code - vendor code
- name - vendor name
- description - vendor description
- url - vendor URL
- email - vendor email address
Example
'http://www.spvsoftwareproducts.com', 'stephen@spvsoftwareproducts.com');
LTI_Tool_Info
This class defines basic details about the tool.
Constructor
function __construct($code, $name, $version, $description, $email, $digestAlgorithm, $baseURL, $iconBaseURL, $actionPrefix)
where:
- $code is a value identifying the tool
- $name is the name of the tool
- $version is the version of the tool
- $description is a description of the tool
- $email is a contact email address for enquries about the tool
- $digestAlgorithm is the digest algorithm used (currently this class only supports MD5
- $baseURL is the base for all URLs provided for menu actions
- $iconBaseURL is the base for all URLs provided for icons
- $actionPrefix is the full URL prefix onto which the menu actions are added
Properties
- code - tool code
- name - tool name
- version - tool version
- description - tool description
- email - tool email address
- digestAlgorithm - tool digest algorithm
- baseURL - base URL
- iconBaseURL - base URL for icons
- actionPrefix - prefix to insert before action names in URLs
- target - preferred location for rendering the output (window, frame or iframe)
- window_name - name of new window (optional)
- height - height of location in which output is to be rendered (optional)
- width - width of location in which output is to be rendered (optional)
Example
'stephen@spvsoftwareproducts.com', 'MD5',
APP__WWW, APP__WWW . '/images', '/lti.php/');
(APP__WWW is assumed to be a constant which contains the URL to the root of the application.)
LTI_Menu
This class defines a menu item; it should have at least one category and one action associated with it.
Constructor
function __construct($id, $name, $description, $url, $target)
where:
- $id is a unique identifier for the menu instance
- $name is the name of the menu item
- $description is the description of the menu item
- $url is the URL to be called when the menu item is selected (this should be relative to the base URL as specified in the LTI_Tool_Info class)
- $target destination for the output: window, frame or iframe
The name and description should also be included in the language bundle(s) with a key of id.name, where id is the id specified for the menu; for example, assuming an id of "courseTool", the en_GB language bundle should include lines like:
courseTool.description=This is my course tool
Methods
- addCategory($category) - add a category for the menu to determine where it is placed (see LTI_Category object below)
- addIcon($icon) - add an icon to associate with the menu (see LTI_Icon object below)
- setParameter($name, $value) - add a parameter name with a value of a capability to be passed with calls to this menu link
Properties
- id - the unique identifier for the menu instance
- name - the name of the menu
- description - the description of the menu
- url - the URL to call when the menu item is selected
- target - the destination for the output: window, frame or iframe
- parameters - an associative array of parameters associated with the menu
- categories - an array of LTI_Category objects associated with the menu
- icons - an array of LTI_Icon objects associated with the menu
Example
...
$tool_producer->menus[] = $menu;
LTI_Category
This class defines where a menu item is to be placed within the tool consumer; for example, 'tool', 'course_tool', 'group_tool', 'user_tool', 'system_tool' (for Moodle specify a category of 'context-tool'). The default platform (NULL) is not supported by Blackboard Learn 9, so a platform of 'blackboard' should be included in the tool specification and should precede an entry without a platform name which will be used by Moodle.
Constructor
function __construct($name, $platform = NULL)
where:
- $name the category name
- $platform the platform to which this category applies
Properties
- name - the name of the category
- platform - the name of the platform to which the category applies
Example
$menu->addCategory(new LTI_Category('context-tool'));
LTI_Icon
This class defines an icon which may be associated with a menu item or content handler. A different icon file can be associated with different tool consumer platforms so that icons of the appropriate size can be used.
Constructor
function __construct($url, $platform = NULL, $style = NULL)
where:
- $url is the URL to the icon file (this should be relative to the base URL as specified in the LTI_Tool_Info class)
- $platform (optional) is the name of the platform for which the icon is to be used (e.g. "blackboard")
- $style (optional) is the type of icon (e.g. "toolbar" or "listitem")
Properties
- url - the URL of the icon file
- platform - the platform to which the icon file applies
- style - the type of icon
Example
LTI_ContentHandler
This class defines a content handler. A callback function with the same name as the id should be defined and will be called whenever an action of this name is received. The callback function should be able to handle the standard subactions of 'create', 'modify', 'remove', 'view' and 'viewattempt'.
Constructor
function __construct($id, $name, $handle)
where:
- $id is the unique identifier for the content handler
- $name is the name of the content handler
- $handle is a unique resource type for the content (e.g. "resource/x-my.content.type")
Methods
- addIcon($icon) - add an icon to associate with the menu (see LTI_Icon object below)
Properties
- id - unique identifier of the content handler instance
- name - name of the content type
- handle - unique resource type for the content
- icons - an array of LTI_Icon objects associated with the content handler
Example
$contentHandler->addIcon(new LTI_Icon('/tool/appbar_webpa_logo.png'));
$contentHandler->addIcon(new LTI_Icon('/images/tool/appbar_webpa_logo.png', 'blackboard', 'listitem'));
$tool_producer->contentHandlers[] = $contentHandler;
LTI_WebService
This class defines the properties of a web service required by the tool producer.
Constructor
function __construct($name, $operations)
where:
- $name is the name of the web service
- $operations is an array containing the name of each of the required methods
Properties
- name - name of web service
- operations - array of method names
LTI_User
This class is created when a connection is made and defines the user requesting the current action. If the fullname of the user is not provided by the tool consumer, this property will be set to the firstname and lastname separated by a space. If the fullname is provided by the tool consumer but not the firstname and/or lastname, the fullname is split at the first space to provide values for the missing firstname and lastname properties.
Constructor
function __construct($id)
where:
- $id is the user ID
Methods
- isAdmin() - returns true if the user has an administrator role, false otherwise
- isStaff() - returns true if the user has a staff role (instructor, content developer or teaching assistant, false otherwise
- isLearner() - returns true if the user has a learner role, false otherwise
Properties
- id - user's ID
- firstname - user's firstname
- lastname - user's lastname
- fullname - user's full name
- email - user's email address
- roles - an array of roles associated with the user
LTI_Context
This class is created when a connection is made and defines the context from which the current request has been sent; typically this will be a course.
Constructor
function __construct($id)
where:
- $id is the id of the context
Properties
- id - context id
- title - context title
- return_url - URL to use when redirecting users back to the context
LTI_Tool_Consumer
This class defines the properties of a tool consumer. It is identified by the GUID supplied from the tool consumer profile or, for Basic LTI connections, as agreed with the administrator of the tool consumer (typically the domain name). The LTI_Tool_Producer class automatically populates an instance of this class with details obtained from the tool consumer profile (either directly from the URL or from data saved in the database).
Constructor
function __construct($dbTableNamePrefix = '', $guid = NULL, $autoEnable = FALSE)
where:
- $dbTableNamePrefix is an optional prefix to use for the names of the database tables
- $guid is an optional value which identifies the tool consumer, if specified the load() method is automatically called
- $autoEnable (optional) will automatically enable the tool consumer when set to true
Methods
- load($guid) - load the details of the specified tool consumer from the database
- save() - save the details of the tool consumer to the database (updating the record if it already exists)
- delete() - delete the details of the tool consumer from the database
Properties
- guid - the tool consumer ID
- name - the name of the tool consumer
- profile_url - the URL from which the tool consumer profile can be obtained
- consumer_name - the name of the system being used as the tool consumer (e.g. "blacboard")
- consumer_version - the version of the system being used as the tool consumer
- vendor_code - the code of the vendor of the system being used as the tool consumer
- css_path - URL path to the CSS file
- services - an associative array containing an entry for each web service provided by the tool consumer; each entry has two elements: "url" (the URL for the web service) and "wsdl" (the URL for the WSDL file for the web service)
- capabilities - an array containing an entry for each capability supported by the tool consumer
- enabled - true if connections are permitted from this tool consumer, false otherwise (which is the default)
- created - date and time when this tool consumer was created
- updated - date and time when the details of this tool consumer were last updated
Example
(APP__DB_TABLE_PREFIX is assumed to be a constant which contains the prefix for the application's database table names.)
LTI_Tool_Consumer_Instance
This class defines the properties of an instance of a connection from a tool consumer. It is identified by the GUID supplied from the tool consumer profile or, for Basic LTI connections, as agreed with the administrator of the tool consumer (typically the domain name and the same as the tool consumer GUID). The LTI_Tool_Producer class automatically populates an instance of this class with details obtained during the tool registration process.
Constructor
function __construct($dbTableNamePrefix = '', $guid = NULL)
where:
- $dbTableNamePrefix is an optional prefix to use for the names of the database tables
- $guid is an optional value which identifies the tool consumer instance, if specified the load() method is automatically called
Methods
- load($guid) - load the details of the specified tool consumer instance from the database
- save() - save the details of the tool consumer instance to the database (updating the record if it already exists)
- delete($deleteConsumer = false) - delete the details of the tool consumer instance from the database and optionally try to delete the tool consumer to which it belonged
- isEnabled() - true if the tool consumer to which this instance is related is set to permit connections, false otherwise
- updateState($state) - update the state to the passed value
- saveNonce($nonce) - save a nonce value (return false if it already exists)
- getRandomString($length = 8) - generate a random string of the specified length
Properties
- guid - the tool consumer instance ID
- consumer_guid - the related tool consumer ID
- state - the current state of the tool consumer instance ('registered', 'available', 'reregistered', 'removed' or 'BasicLTI')
- secret - the shared secret used to secure connections with the tool consumer
- created - date and time when this tool consumer was created
- updated - date and time when the details of this tool consumer were last updated
Examples
To create an existing instance of a tool consumer pass the GUID as the second parameter:
(APP__DB_TABLE_PREFIX is assumed to be a constant which contains the prefix for the application's database table names.)
To create a new tool consumer instance omit the second parameter:
LTI_SoapClient
This class extends the SoapClient class to override the __doRequest method to insert the username and password.
Constructor
function __construct($wsdl, $options = array())
where:
- $wsdl is the URL of the WSDL file
- $options is an optional associative array containing username and password values for the connection
Usage
Callback functions
Each callback function is associated with an LTI action by the associative array passed to the constructor of the LTI_Tool_Producer object. The return value of these callback functions may be one of the following:
- a boolean value representing success or failure of the request
- a string starting with 'http://' or 'https://' representing the URL to redirect a user to
- a string containing the text to be returned to the tool consumer (unless a return URL was specified in the request in which case a user is redirected to this URL)
Basic LTI support
For Basic LTI there is only a single action to support, when a user is redirected from the tool consumer to the tool producer. This action can be given any name, other than one reserved for Full LTI. It will also be taken as the default action and so does not need to be specified in the URL. For example, including the following code in the script to which a user is redirected via a Basic LTI connection, will validate the request and, if authenticated, the doConnect method will be called. This method may be used to:
- create the user account if it does not already exist (or update it if it does);
- create the context if it does not already exist (or update it if it does);
- set up a new session for the user (or otherwise log the user into the tool producer application)
- keep a record of the return URL for the tool consumer (for example, as a session variable)
- return the URL for the home page of the application so the user may be redirected to it (or false if the connection request is not accepted)
require_once('include/classes/lti/LTI_Tool_Producer.php');
...
$tool = new LTI_Tool_Producer(array('connect' => 'doConnect'), '');
...
function doConnect($tool_producer) {
// Insert code here to handle incoming connections - use the user
// and context properties of the $tool_producer parameter
// to access the current user and context.
...
return 'https://www.tool.producer.com/index.php';
}
This script may be called in either of the following ways; the last two examples will use the first action in the callback handlers passed when creating the LTI_Tool_Producer object:
- https://www.tool.producer.com/lti_request.php/connect
- https://www.tool.producer.com/lti_request.php?lti_action=connect
- https://www.tool.producer.com/lti_request.php?lti_action=
- https://www.tool.producer.com/lti_request.php
"Full" LTI support
For a "Full" LTI integration, several actions will be requested by the tool consumer, of which the following are likely to require a callback handler to be defined so that code specific to the application can be executed:
- tool-provision - called when a request to register the tool is received
- bundle - called whenever text is to be rendered by the tool consumer in a new language
- connect - called whenever a user attempts to connect to the tool
require_once('include/classes/lti/LTI_Tool_Producer.php');
...
$tool = new LTI_Tool_Producer(array('tool-provision' => 'getProfile', 'bundle' => 'getBundle', 'connect' => 'doConnect'),
$dbprefix);
...
function getProfile($tool_producer) {
// Insert code here to define the properties of the tool producer: vendor, tool information, menu(s), content handler(s).
...
$tool_producer->vendor = new LTI_Vendor('xyz', 'XYZ Software Inc', 'Distributor of educational software',
'http://www.xyzsoftware.com', 'sales@xyzsoftware.com');
$tool_producer->tool_info = new LTI_Tool_Info('LTI tool', 'An LTI tool', '1.0',
'This is an LTI-compliant tool', 'support@xyzsoftware.com', 'MD5',
'https://www.xyzsoftware.com/tool','https://www.xyzsoftware.com/tool/images','/lti.php/');
$menu = new LTI_Menu('tool', 'LTI tool', 'An example LTI tool', 'connect/course', 'frame');
$menu->addCategory(new LTI_Category('tool', 'blackboard'));
$menu->addIcon(new LTI_Icon('/images/tool_logo.gif', 'blackboard', 'listitem'));
$tool_producer->menus[] = $menu;
// repeat the above 4 lines for any additional menu placements (using a different URL for each if required)
$contentHandler = new LTI_ContentHandler('content', 'LTI tool', 'resource/x-xyz-ltitool');
$contentHandler->addIcon(new LTI_Icon('/images/content_logo.gif', 'blackboard', 'listitem'));
$tool_producer->contentHandlers[] = $contentHandler;
// repeat the above 3 lines for any additional content handlers (using a different id and resource type for each)
...
}
...
function getBundle($tool_producer) {
$locale = $tool_producer->getLocale();
switch ($locale) {
case 'en_GB':
$bundle = ...
break;
default:
$bundle = "tool.name=LTI tool\n";
$bundle .= "tool.description=An example LTI tool\n";
$bundle .= "content.name=LTI tool\n";
$bundle .= "content.description=An example LTI tool using a content handler\n";
}
return $bundle;
}
...
function doConnect($tool_producer) {
// Insert code here to handle incoming connections - use the user
// and context properties of the $tool_producer parameter
// to access the current user and context.
...
return 'https://www.xyzsoftware.com/tool/index.php';
}
Version history
Version | Date | Description |
---|---|---|
1.0.00 | 8 February 2011 | First public release |
1.1.00 | 26 February 2011 |
Added support for draft Moodle implementation of Full LTI:
Actions may be passed in a query parameter named lti_action as an alternative to being placed on the path |
1.1.01 | 17 April 2011 |
Permit subactions when actions passed as query parameter Changed BasicLTI to use oauth_consumer_key as ID Minor bug fixes |
Licence
This work is written by Stephen Vickers and is released under a Creative Commons GNU General Public Licence. The LTI Tool Producer PHP class is available for download from OSCELOT where it is also possible to report bugs and submit feature requests.