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:

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:

CREATE TABLE IF NOT EXISTS lti_consumer (
  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_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:

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

Properties

Examples

A minimal example for supporting Basic LTI only:

$tool = new LTI_Tool_Producer(array('connect' => 'doConnect'), APP__DB_TABLE_PREFIX);

(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:

$tool_producer = new LTI_Tool_Producer(array('connect' => 'doConnect', 'tool-provision' => 'getProfile',
                                    '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

Example

$tool_producer->vendor = new LTI_Vendor('spvsp', 'SPV Software Products', 'Producer of educational software',
                                        '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

Example

$tool_producer->tool_info = new LTI_Tool_Info('WebPA', 'WebPA OS', '0.1', 'WebPA proxy tool',
                                              '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.name=My course tool
courseTool.description=This is my course tool

Methods

Properties

Example

$menu = new LTI_Menu('tool', 'WebPA', 'WebPA OS', 'connect/user', 'window');
...
$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

Example

$menu->addCategory(new LTI_Category('tool', 'blackboard'));
$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

Example

$menu->addIcon(new LTI_Icon('/tool/appbar_webpa_logo.png'));

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

Properties

Example

$contentHandler = new LTI_ContentHandler('ch', 'WebPA tool', 'resource/x-spvsp-webpa');
$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

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

Properties

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

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

Properties

Example

$consumer = new LTI_Tool_Consumer(APP__DB_TABLE_PREFIX, $consumer_instance_guid);

(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

Properties

Examples

To create an existing instance of a tool consumer pass the GUID as the second parameter:

$consumer_instance = new LTI_Tool_Consumer_Instance(APP__DB_TABLE_PREFIX, $tool_consumer_guid);

(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:

$consumer_instance = new LTI_Tool_Consumer_Instance(APP__DB_TABLE_PREFIX);

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:

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:

...

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:

"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:

...

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

VersionDateDescription
1.0.008 February 2011First public release
1.1.0026 February 2011

Added support for draft Moodle implementation of Full LTI:

  • iconBaseURL added to LTI_Tool_Info class
  • autoEnable added to LTI_Tool_Producer and LTI_Tool_Consumer classes
  • target added to LTI_Tool_Producer and LTI_Menu classes
  • actions, required_capabilities, window_name, height and width added to LTI_Tool_Producer class
  • parameters added to LTI_Menu class
  • capabilities added to LTI_Tool_Consumer class
  • capabilities field added to lti_consumer database table

Actions may be passed in a query parameter named lti_action as an alternative to being placed on the path

1.1.0117 April 2011 Permit subactions when actions passed as query parameter
Changed BasicLTI to use oauth_consumer_key as ID
Minor bug fixes

Licence

Creative Commons License 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.

Valid XHTML 1.0 Strict