Skip to content

Installation

Stephen Vickers edited this page Jan 8, 2024 · 14 revisions

PHP source files

This page describes the installation of version 4+ of the library; follow this link for details relating to version 3.

Using Composer

Add the following entry to the require element of the composer.json file for your web application:

  "require" : {
    "celtic/lti": "^5.0.0"
  },

(or use 4.0.0 for version 4 of the library). In a command-line interface, change directory to the root of your web application and run the following command:

composer install

Then, add the following to your PHP script:

require_once('vendor/autoload.php');

Manual installation

To install the library, clone the src directory from the repository into your desired application directory (for example, .../vendor/ceLTIc/LTI/src). The same should be done for the dependent Firebase JWT library.

The class files can be automatically loaded into your web application by loading a file like the following (which is assumed to be located in the vendor directory where the dependent classes have been installed):

<?php
/**
 * Autoload a class file.
 *
 * @param string $class The fully-qualified class name.
 */
 spl_autoload_register(function ($class) {

     // base directory for the class files
     $base_dir = __DIR__ . DIRECTORY_SEPARATOR;

     // Replace the namespace prefix with the base directory, replace namespace
     // separators with directory separators in the relative class name, append
     // with .php
     $file = $base_dir . preg_replace('/[\\\\\/]/', DIRECTORY_SEPARATOR, $class) . '.php';

     // Update location if class requested is from the ceLTIc\LTI class library
     $file = str_replace(DIRECTORY_SEPARATOR . 'ceLTIc' . DIRECTORY_SEPARATOR . 'LTI' . DIRECTORY_SEPARATOR,
         DIRECTORY_SEPARATOR . 'celtic' . DIRECTORY_SEPARATOR . 'lti' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $file);

     // Update location if class requested is from the Firebase\php-jwt class library
     $file = str_replace(DIRECTORY_SEPARATOR . 'Firebase' . DIRECTORY_SEPARATOR . 'JWT' . DIRECTORY_SEPARATOR,
         DIRECTORY_SEPARATOR . 'firebase' . DIRECTORY_SEPARATOR . 'php-jwt' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR,
         $file);

     // If the file exists, require it
     if (file_exists($file)) {
         require($file);
     }
 });

?>

If needed, change the value of the $base_dir variable to wherever you located the library files.

WordPress

A plugin named ceLTIc LTI Library is available from the WordPress Plugins repository for use with a WordPress plugin (such as the LTI Tool plugin).

Database tables

The library uses a set of database files to record LTI-related data, including the keys and secrets issued to tool consumers. The DDL for creating these tables is given below. The library supports adding a prefix to the table names so that, for example, you may wish to change lti2_consumer to something like app1_lti2_consumer. If you want to change the name of the table itself, make sure you update the constants in the DataConnector class file. You may also adapt this structure to integrate it with your own application tables - just create your own subclass of the DataConnector\DataConnector class to implement the SQL to access the required objects from wherever they exist in your database (or other storage device).

The library supports the following databases as standard; follow the link for an SQL script to create the tables:

Use the Tool link when adding the library to a tool; use the Platform link when your application is acting as a platform.

The MySQL scripts are shown here by way of examples.

MySQL Tool:

CREATE TABLE lti2_consumer (
  consumer_pk int(11) NOT NULL AUTO_INCREMENT,
  name varchar(50) NOT NULL,
  consumer_key varchar(255) DEFAULT NULL,
  secret varchar(1024) DEFAULT NULL,
  platform_id VARCHAR(255) DEFAULT NULL,
  client_id VARCHAR(255) DEFAULT NULL,
  deployment_id VARCHAR(255) DEFAULT NULL,
  public_key text DEFAULT NULL,
  lti_version varchar(10) DEFAULT NULL,
  signature_method varchar(15) NOT NULL DEFAULT 'HMAC-SHA1',
  consumer_name varchar(255) DEFAULT NULL,
  consumer_version varchar(255) DEFAULT NULL,
  consumer_guid varchar(1024) DEFAULT NULL,
  profile text DEFAULT NULL,
  tool_proxy text DEFAULT NULL,
  settings text DEFAULT NULL,
  protected tinyint(1) NOT NULL,
  enabled tinyint(1) NOT NULL,
  enable_from datetime DEFAULT NULL,
  enable_until datetime DEFAULT NULL,
  last_access date DEFAULT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (consumer_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_consumer
  ADD UNIQUE INDEX lti2_consumer_consumer_key_UNIQUE (consumer_key ASC);

ALTER TABLE lti2_consumer
  ADD UNIQUE INDEX lti2_consumer_platform_UNIQUE (platform_id ASC, client_id ASC, deployment_id ASC);

CREATE TABLE lti2_nonce (
  consumer_pk int(11) NOT NULL,
  value varchar(50) NOT NULL,
  expires datetime NOT NULL,
  PRIMARY KEY (consumer_pk, value)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_nonce
  ADD CONSTRAINT lti2_nonce_lti2_consumer_FK1 FOREIGN KEY (consumer_pk)
  REFERENCES lti2_consumer (consumer_pk);

CREATE TABLE lti2_access_token (
  consumer_pk int(11) NOT NULL,
  scopes text NOT NULL,
  token varchar(2000) NOT NULL,
  expires datetime NOT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (consumer_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_access_token
  ADD CONSTRAINT lti2_access_token_lti2_consumer_FK1 FOREIGN KEY (consumer_pk)
  REFERENCES lti2_consumer (consumer_pk);

CREATE TABLE lti2_context (
  context_pk int(11) NOT NULL AUTO_INCREMENT,
  consumer_pk int(11) NOT NULL,
  title varchar(255) DEFAULT NULL,
  lti_context_id varchar(255) NOT NULL,
  type varchar(50) DEFAULT NULL,
  settings text DEFAULT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (context_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_context
  ADD CONSTRAINT lti2_context_lti2_consumer_FK1 FOREIGN KEY (consumer_pk)
  REFERENCES lti2_consumer (consumer_pk);

ALTER TABLE lti2_context
  ADD INDEX lti2_context_consumer_id_IDX (consumer_pk ASC);

CREATE TABLE lti2_resource_link (
  resource_link_pk int(11) AUTO_INCREMENT,
  context_pk int(11) DEFAULT NULL,
  consumer_pk int(11) DEFAULT NULL,
  title varchar(255) DEFAULT NULL,
  lti_resource_link_id varchar(255) NOT NULL,
  settings text,
  primary_resource_link_pk int(11) DEFAULT NULL,
  share_approved tinyint(1) DEFAULT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (resource_link_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_resource_link
  ADD CONSTRAINT lti2_resource_link_lti2_consumer_FK1 FOREIGN KEY (consumer_pk)
  REFERENCES lti2_consumer (consumer_pk);

ALTER TABLE lti2_resource_link
  ADD CONSTRAINT lti2_resource_link_lti2_context_FK1 FOREIGN KEY (context_pk)
  REFERENCES lti2_context (context_pk);

ALTER TABLE lti2_resource_link
  ADD CONSTRAINT lti2_resource_link_lti2_resource_link_FK1 FOREIGN KEY (primary_resource_link_pk)
  REFERENCES lti2_resource_link (resource_link_pk);

ALTER TABLE lti2_resource_link
  ADD INDEX lti2_resource_link_consumer_pk_IDX (consumer_pk ASC);

ALTER TABLE lti2_resource_link
  ADD INDEX lti2_resource_link_context_pk_IDX (context_pk ASC);

CREATE TABLE lti2_user_result (
  user_result_pk int(11) AUTO_INCREMENT,
  resource_link_pk int(11) NOT NULL,
  lti_user_id varchar(255) NOT NULL,
  lti_result_sourcedid varchar(1024) NOT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (user_result_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_user_result
  ADD CONSTRAINT lti2_user_result_lti2_resource_link_FK1 FOREIGN KEY (resource_link_pk)
  REFERENCES lti2_resource_link (resource_link_pk);

ALTER TABLE lti2_user_result
  ADD INDEX lti2_user_result_resource_link_pk_IDX (resource_link_pk ASC);

CREATE TABLE lti2_share_key (
  share_key_id varchar(32) NOT NULL,
  resource_link_pk int(11) NOT NULL,
  auto_approve tinyint(1) NOT NULL,
  expires datetime NOT NULL,
  PRIMARY KEY (share_key_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_share_key
  ADD CONSTRAINT lti2_share_key_lti2_resource_link_FK1 FOREIGN KEY (resource_link_pk)
  REFERENCES lti2_resource_link (resource_link_pk);

ALTER TABLE lti2_share_key
  ADD INDEX lti2_share_key_resource_link_pk_IDX (resource_link_pk ASC);

MySQL Platform:

CREATE TABLE lti2_tool (
  tool_pk int(11) NOT NULL AUTO_INCREMENT,
  name varchar(50) NOT NULL,
  consumer_key varchar(255) DEFAULT NULL,
  secret varchar(1024) DEFAULT NULL,
  message_url varchar(255) DEFAULT NULL,
  initiate_login_url varchar(255) DEFAULT NULL,
  redirection_uris text DEFAULT NULL,
  public_key text DEFAULT NULL,
  lti_version varchar(10) DEFAULT NULL,
  signature_method varchar(15) DEFAULT NULL,
  settings text DEFAULT NULL,
  enabled tinyint(1) NOT NULL,
  enable_from datetime DEFAULT NULL,
  enable_until datetime DEFAULT NULL,
  last_access date DEFAULT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (tool_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_tool
  ADD UNIQUE INDEX lti2_tool_initiate_login_url_UNIQUE (initiate_login_url ASC);

Migrating from version 4 to version 5

Version 5 is an updated for PHP 8.1+ and requires some code changes where new PHP features have been utilised (e.g. Enumerations). See the Updating page for full details.

Migrating from version 3 to version 4

Updating to the version 4 release of the LTI class library from the version 3 requires alterations to the database structure and optional changes to the PHP source files.

Database alterations

Version 4 requires the following changes to the lti2_consumer table:

  • Remove consumer_key column
  • Change name of consumer_key256 column to consumer_key, its data type to VARCHAR(255) and remove NOT NULL constraint (ensure the existing unique index on the consumer_key column is retained)
  • Remove NOT NULL constraint from secret column
  • Insert platform_id, client_id, deployment_id and public_key columns
  • Add a unique index on the platform_id, client_id, deployment_id columns
  • Add the lti2_access_token table

Since version 4 removes support for platforms with consumer keys longer than 255 characters, any existing platforms which fit into this category should be removed from the system before updating. Otherwise all existing data will remain in place; the changes merely add new columns.

The MySQL statements for making these changes are as follows:

ALTER TABLE lti2_consumer
  DROP COLUMN consumer_key,
  CHANGE COLUMN consumer_key256 consumer_key VARCHAR(255) DEFAULT NULL,
  CHANGE COLUMN secret secret VARCHAR(1024) DEFAULT NULL,
  ADD COLUMN platform_id VARCHAR(255) DEFAULT NULL AFTER secret,
  ADD COLUMN client_id VARCHAR(255) DEFAULT NULL AFTER platform_id,
  ADD COLUMN deployment_id VARCHAR(255) DEFAULT NULL AFTER client_id,
  ADD COLUMN public_key text DEFAULT NULL AFTER deployment_id;

ALTER TABLE lti2_consumer
  ADD UNIQUE INDEX lti2_consumer_platform_UNIQUE (platform_id ASC, client_id ASC, deployment_id ASC);

CREATE TABLE lti2_access_token (
  consumer_pk int(11) NOT NULL,
  scopes text NOT NULL,
  token varchar(2000) NOT NULL,
  expires datetime NOT NULL,
  created datetime NOT NULL,
  updated datetime NOT NULL,
  PRIMARY KEY (consumer_pk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE lti2_access_token
  ADD CONSTRAINT lti2_access_token_lti2_consumer_FK1 FOREIGN KEY (consumer_pk)
  REFERENCES lti2_consumer (consumer_pk);

Update for SQL Server

Any implementation created with version 4.6.4 (or prior) using the default tables with a SQL Server database should update the constraints on the platform and tool tables using SQL statements such as:

ALTER TABLE lti2_consumer DROP CONSTRAINT UC_lti2_consumer_consumer_key;

ALTER TABLE lti2_consumer DROP CONSTRAINT UC_lti2_consumer_platform;

CREATE UNIQUE INDEX UC_lti2_consumer_consumer_key ON lti2_consumer
  (consumer_key) WHERE (consumer_key IS NOT NULL);

CREATE UNIQUE INDEX UC_lti2_consumer_platform ON lti2_consumer
  (platform_id, client_id, deployment_id)
  WHERE (platform_id IS NOT NULL) AND (client_id IS NOT NULL) AND
   (deployment_id IS NOT NULL);
ALTER TABLE lti2_tool DROP CONSTRAINT UC_lti2_tool_initiate_login_url;

CREATE UNIQUE INDEX UC_lti2_tool_initiate_login_url ON lti2_tool
  (initiate_login_url) WHERE (initiate_login_url IS NOT NULL);

The above statements should be adjusted if a table name prefix is being used.

PHP source file changes

The library has been updated to use the latest LTI terminology of Platform and Tool rather than Tool Consumer and Tool Provider. This involves changes to the names of classes, methods and properties, but the old names have not been removed, they are just deprecated. So the following changes are recommended but optional at this time:

  • Change all ceLTIc/LTI/ToolConsumer class references to ceLTIc/LTI/Platform and use the Platform::fromConsumerKey() method instead of the class constructor.
  • Change all ceLTIc/LTI/ToolProvider class references to ceLTIc/LTI/Tool.
  • Change all uses of the getConsumer(), getConsumerId() and setConsumerId(), methods to getPlatform(), getPlatformId() and setPlatformId(), respectively, in the ResourceLink class.
  • Change all uses of the fromConsumer() method to fromPlatform() in the Context and ResourceLink classes.
  • Change all uses of the LTI_VERSION1 and LTI_VERSION2 constants from the ToolProvider class to the Util class.
  • Change all uses of the getRandomString() method from the DataConnector class to the Util class.

See the Deprecated list in the class definition documentation for more details.