Skip to content

Installation

Stephen Vickers edited this page Jun 12, 2020 · 14 revisions

PHP source files

Using Composer

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

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

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 class files can be automatically loaded into your web application by loading a file like the following:

<?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 . 'vendor' . 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 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);

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

 });

?>

Just change the value of the $base_dir variable to wherever you located the library files.

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 class to implement the SQL to access the required objects from wherever they exist in your database.

Database supports

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

The MySQL script is shown here as an example.

CREATE TABLE lti2_consumer (
  consumer_pk int(11) NOT NULL AUTO_INCREMENT,
  name varchar(50) NOT NULL,
  consumer_key256 varchar(256) NOT NULL,
  consumer_key text DEFAULT NULL,
  secret varchar(1024) NOT 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_key256 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_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);

Updating from previous versions

Updating to this release of the LTI class library from previous related versions may require alterations to the PHP source files and to the database structure.

PHP source file changes

Review the Usage section of this site and the code documentation for examples of how to reference and access the LTI classes. A sample tool provider named Rating is also available to illustrate the use of the library.

Database alterations

Create new database tables (see above) and use the following migration script (modify for databases other than MySQL) to copy the data from the old tables. Once complete and tested the old LTI tables can be deleted. (Remember to add a table name prefix to the script if one is being used.)

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE lti2_user_result;
TRUNCATE TABLE lti2_share_key;
TRUNCATE TABLE lti2_resource_link;
TRUNCATE TABLE lti2_context;
TRUNCATE TABLE lti2_nonce;
TRUNCATE TABLE lti2_consumer;
SET FOREIGN_KEY_CHECKS = 1;

-- Consumers
INSERT INTO lti2_consumer (name, consumer_key256, consumer_key, secret, lti_version,
    signature_method, consumer_name, consumer_version, consumer_guid, profile, tool_proxy,
    settings, protected, enabled, enable_from, enable_until, last_access, created, updated)
  SELECT name, consumer_key, NULL, secret, lti_version,
    'HMAC-SHA1', consumer_name, consumer_version, consumer_guid, NULL, NULL,
    NULL, protected, enabled, enable_from, enable_until, last_access, created, updated
  FROM lti_consumer;

-- Nonces
INSERT INTO lti2_nonce (consumer_pk, value, expires)
  SELECT c.consumer_pk, n.value, n.expires
  FROM lti_nonce n INNER JOIN lti2_consumer c ON n.consumer_key = c.consumer_key256;

-- Contexts
INSERT INTO lti2_context (consumer_pk, title, lti_context_id, type, settings, created, updated)
  SELECT c.consumer_pk, IF(INSTR(x.title, ':') > 0, SUBSTRING(x.title, 1, INSTR(x.title, ':') - 1), ''), x.lti_context_id, NULL, NULL, x.created, x.updated
  FROM lti_context x INNER JOIN lti2_consumer c ON x.consumer_key = c.consumer_key256
  WHERE x.lti_context_id IS NOT NULL
  GROUP BY c.consumer_pk, x.lti_context_id;

-- Resource links without contexts
INSERT INTO lti2_resource_link (context_pk, consumer_pk, title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated)
  SELECT x.context_pk, c.consumer_pk, r.title, r.lti_resource_id, r.settings, NULL, NULL, r.created, r.updated
  FROM lti_context r INNER JOIN lti2_consumer c ON r.consumer_key = c.consumer_key256
    LEFT OUTER JOIN lti2_context x ON x.lti_context_id = r.lti_context_id
    WHERE r.lti_context_id IS NULL;

-- Resource links for contexts
INSERT INTO lti2_resource_link (context_pk, consumer_pk, title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated)
  SELECT x.context_pk, NULL, IF(INSTR(r.title, ':') > 0, TRIM(SUBSTRING(r.title, INSTR(r.title, ':') + 1)), r.title), r.lti_resource_id, r.settings, NULL, NULL, r.created, r.updated
  FROM lti_context r INNER JOIN lti2_consumer c ON r.consumer_key = c.consumer_key256
    INNER JOIN lti2_context x ON x.lti_context_id = r.lti_context_id
  GROUP BY c.consumer_pk, r.context_id, r.lti_context_id;

-- Update resource link shares
UPDATE lti2_resource_link r
  INNER JOIN lti_context x ON (x.context_id = r.lti_resource_link_id)
  INNER JOIN lti2_consumer c ON c.consumer_key256 = x.consumer_key
  INNER JOIN lti2_resource_link r2 ON (x.primary_context_id = r2.lti_resource_link_id)
  INNER JOIN lti2_consumer c2 ON c2.consumer_pk = r2.consumer_pk
SET r.primary_resource_link_pk = r2.resource_link_pk, r.share_approved = x.share_approved;

-- Share keys
INSERT INTO lti2_share_key (share_key_id, resource_link_pk, auto_approve, expires)
  SELECT s.share_key_id, r.resource_link_pk, s.auto_approve, s.expires
  FROM lti_share_key s INNER JOIN lti2_resource_link r ON s.primary_context_id = r.lti_resource_link_id
    INNER JOIN lti2_consumer c ON r.consumer_pk = c.consumer_pk
  WHERE c.consumer_key256 = s.primary_consumer_key;

-- User results
INSERT INTO lti2_user_result (resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated)
  SELECT r.resource_link_pk, u.user_id, u.lti_result_sourcedid, u.created, u.updated
  FROM lti_user u INNER JOIN lti2_resource_link r ON u.context_id = r.lti_resource_link_id
    INNER JOIN lti2_consumer c ON r.consumer_pk = c.consumer_pk
  WHERE c.consumer_key256 = u.consumer_key;

PHP source file changes

  • Change all IMSGlobal/LTI/ToolProvider namespace references to ceLTIc/LTI.
  • Reverse the order of the $dbTableNamePrefix and $db parameters in calls to the getDataConnector method.

Database alterations

  • lti2_consumer table: add field signature_method varchar(15) NOT NULL DEFAULT 'HMAC-SHA1'
  • drop lti2_tool_proxy table
  • lti2_nonce table: change size of value field to 50
  • lti2_context table: add fields title varchar(255) DEFAULT NULL and type varchar(50) DEFAULT NULL
  • lti2_resource_link table: add field title varchar(255) DEFAULT NULL
Clone this wiki locally