LTI Integration Library  3.1.0
PHP class library for building LTI integrations
ToolConsumer.php
Go to the documentation of this file.
1 <?php
2 
3 namespace ceLTIc\LTI;
4 
9 
19 {
20 
26  public $name = null;
27 
33  public $secret = null;
34 
40  public $ltiVersion = null;
41 
47  public $signatureMethod = 'HMAC-SHA1';
48 
54  public $consumerName = null;
55 
61  public $consumerVersion = null;
62 
68  public $profile = null;
69 
75  public $consumerGuid = null;
76 
82  public $cssPath = null;
83 
89  public $protected = false;
90 
96  public $enabled = false;
97 
103  public $enableFrom = null;
104 
110  public $enableUntil = null;
111 
117  public $lastAccess = null;
118 
125 
131  public $defaultEmail = '';
132 
138  public $lastServiceRequest = null;
139 
145  public $created = null;
146 
152  public $updated = null;
153 
159  private $id = null;
160 
166  private $key = null;
167 
173  private $settings = null;
174 
180  private $settingsChanged = false;
181 
187  private $dataConnector = null;
188 
196  public function __construct($key = null, $dataConnector = null, $autoEnable = false)
197  {
198  $this->initialize();
199  if (empty($dataConnector)) {
201  }
202  $this->dataConnector = $dataConnector;
203  if (!is_null($key) && (strlen($key) > 0)) {
204  $this->load($key, $autoEnable);
205  } else {
207  }
208  }
209 
213  public function initialize()
214  {
215  $this->id = null;
216  $this->key = null;
217  $this->name = null;
218  $this->secret = null;
219  $this->signatureMethod = 'HMAC-SHA1';
220  $this->ltiVersion = null;
221  $this->consumerName = null;
222  $this->consumerVersion = null;
223  $this->consumerGuid = null;
224  $this->profile = null;
225  $this->toolProxy = null;
226  $this->settings = array();
227  $this->protected = false;
228  $this->enabled = false;
229  $this->enableFrom = null;
230  $this->enableUntil = null;
231  $this->lastAccess = null;
232  $this->idScope = ToolProvider::ID_SCOPE_ID_ONLY;
233  $this->defaultEmail = '';
234  $this->created = null;
235  $this->updated = null;
236  }
237 
243  public function initialise()
244  {
245  $this->initialize();
246  }
247 
253  public function save()
254  {
255  $ok = $this->dataConnector->saveToolConsumer($this);
256  if ($ok) {
257  $this->settingsChanged = false;
258  }
259 
260  return $ok;
261  }
262 
268  public function delete()
269  {
270  return $this->dataConnector->deleteToolConsumer($this);
271  }
272 
278  public function getRecordId()
279  {
280  return $this->id;
281  }
282 
288  public function setRecordId($id)
289  {
290  $this->id = $id;
291  }
292 
298  public function getKey()
299  {
300  return $this->key;
301  }
302 
308  public function setKey($key)
309  {
310  $this->key = $key;
311  }
312 
318  public function getFamilyCode()
319  {
320  $familyCode = '';
321  if (!empty($this->consumerVersion)) {
322  list($familyCode, $version) = explode('-', $this->consumerVersion, 2);
323  }
324 
325  return $familyCode;
326  }
327 
333  public function getDataConnector()
334  {
335  return $this->dataConnector;
336  }
337 
343  public function getIsAvailable()
344  {
345  $ok = $this->enabled;
346 
347  $now = time();
348  if ($ok && !is_null($this->enableFrom)) {
349  $ok = $this->enableFrom <= $now;
350  }
351  if ($ok && !is_null($this->enableUntil)) {
352  $ok = $this->enableUntil > $now;
353  }
354 
355  return $ok;
356  }
357 
366  public function getSetting($name, $default = '')
367  {
368  if (array_key_exists($name, $this->settings)) {
369  $value = $this->settings[$name];
370  } else {
371  $value = $default;
372  }
373 
374  return $value;
375  }
376 
383  public function setSetting($name, $value = null)
384  {
385  $old_value = $this->getSetting($name);
386  if ($value !== $old_value) {
387  if (!empty($value)) {
388  $this->settings[$name] = $value;
389  } else {
390  unset($this->settings[$name]);
391  }
392  $this->settingsChanged = true;
393  }
394  }
395 
401  public function getSettings()
402  {
403  return $this->settings;
404  }
405 
411  public function setSettings($settings)
412  {
413  $this->settings = $settings;
414  }
415 
421  public function saveSettings()
422  {
423  if ($this->settingsChanged) {
424  $ok = $this->save();
425  } else {
426  $ok = true;
427  }
428 
429  return $ok;
430  }
431 
437  public function hasToolSettingsService()
438  {
439  $has = !empty($this->getSetting('custom_system_setting_url'));
440  if (!$has) {
441  $has = self::hasApiHook(self::$TOOL_SETTINGS_SERVICE_HOOK, $this->getConsumer()->getFamilyCode());
442  }
443  return $has;
444  }
445 
453  public function getToolSettings($simple = true)
454  {
455  $ok = false;
456  $settings = array();
457  if (!empty($this->getSetting('custom_system_setting_url'))) {
458  $url = $this->getSetting('custom_system_setting_url');
459  $service = new Service\ToolSettings($this, $url, $simple);
460  $settings = $service->get($mode);
461  $this->lastServiceRequest = $service->getHTTPMessage();
462  $ok = $settings !== false;
463  }
464  if (!$ok && $this->hasApiHook(self::$TOOL_SETTINGS_SERVICE_HOOK, $this->getConsumer()->getFamilyCode())) {
465  $className = $this->getApiHook(self::$TOOL_SETTINGS_SERVICE_HOOK, $this->getConsumer()->getFamilyCode());
466  $hook = new $className($this);
467  $settings = $hook->getToolSettings($mode, $simple);
468  }
469 
470  return $settings;
471  }
472 
480  public function setToolSettings($settings = array())
481  {
482  $ok = false;
483  if (!empty($this->getSetting('custom_system_setting_url'))) {
484  $url = $this->getSetting('custom_system_setting_url');
485  $service = new Service\ToolSettings($this, $url);
486  $ok = $service->set($settings);
487  $this->lastServiceRequest = $service->getHTTPMessage();
488  }
489  if (!$ok && $this->hasApiHook(self::$TOOL_SETTINGS_SERVICE_HOOK, $this->getConsumer()->getFamilyCode())) {
490  $className = $this->getApiHook(self::$TOOL_SETTINGS_SERVICE_HOOK, $this->getConsumer()->getFamilyCode());
491  $hook = new $className($this);
492  $ok = $hook->setToolSettings($settings);
493  }
494 
495  return $ok;
496  }
497 
508  public function signParameters($url, $type, $version, $params)
509  {
510  if (!empty($url)) {
511 // Add standard parameters
512  $params['lti_version'] = $version;
513  $params['lti_message_type'] = $type;
514 // Add signature
515  $params = $this->addSignature($url, $params, 'POST', $type);
516  }
517 
518  return $params;
519  }
520 
531  public function signServiceRequest($url, $method, $type, $data = null)
532  {
533  $header = '';
534  if (!empty($url)) {
535  $header = $this->addSignature($url, $data, $method, $type);
536  }
537 
538  return $header;
539  }
540 
552  public function addSignature($endpoint, $data, $method = 'POST', $type = null, $forTP = false)
553  {
554  switch ($this->signatureMethod) {
555  case 'HMAC-SHA1':
556  case 'HMAC-SHA224':
557  case 'HMAC-SHA256':
558  case 'HMAC-SHA384':
559  case 'HMAC-SHA512':
560  return $this->addOAuthSignature($endpoint, $data, $method, $type);
561  break;
562  default:
563  return $data;
564  break;
565  }
566  }
567 
578  public function doServiceRequest($service, $method, $format, $data)
579  {
580  $header = $this->addSignature($service->endpoint, $data, $method, $format);
581 
582 // Connect to tool consumer
583  $http = new HTTPMessage($service->endpoint, $method, $data, $header);
584 // Parse JSON response
585  if ($http->send() && !empty($http->response)) {
586  $http->responseJson = json_decode($http->response);
587  $http->ok = !is_null($http->responseJson);
588  }
589 
590  return $http;
591  }
592 
601  public static function fromRecordId($id, $dataConnector)
602  {
603  $toolConsumer = new ToolConsumer(null, $dataConnector);
604 
605  $toolConsumer->initialize();
606  $toolConsumer->setRecordId($id);
607  if (!$dataConnector->loadToolConsumer($toolConsumer)) {
608  $toolConsumer->initialize();
609  }
610 
611  return $toolConsumer;
612  }
613 
614 ###
615 ### PRIVATE METHODS
616 ###
617 
626  private function load($key, $autoEnable = false)
627  {
628  $this->key = $key;
629  $ok = $this->dataConnector->loadToolConsumer($this);
630  if (!$ok) {
631  $this->enabled = $autoEnable;
632  }
633 
634  return $ok;
635  }
636 
642  private function addOAuthSignature($endpoint, $data, $method, $type)
643  {
644  $params = array();
645  if (is_array($data)) {
646  $params = $data;
647  $params['oauth_callback'] = 'about:blank';
648  }
649 // Check for query parameters which need to be included in the signature
650  $queryString = parse_url($endpoint, PHP_URL_QUERY);
651  $queryParams = OAuth\OAuthUtil::parse_parameters($queryString);
652  $params = array_merge_recursive($queryParams, $params);
653 
654  if (!is_array($data)) {
655 // Calculate body hash
656  switch ($this->signatureMethod) {
657  case 'HMAC-SHA224':
658  $hash = base64_encode(hash('sha224', $data, TRUE));
659  break;
660  case 'HMAC-SHA256':
661  $hash = base64_encode(hash('sha256', $data, TRUE));
662  break;
663  case 'HMAC-SHA384':
664  $hash = base64_encode(hash('sha384', $data, TRUE));
665  break;
666  case 'HMAC-SHA512':
667  $hash = base64_encode(hash('sha512', $data, TRUE));
668  break;
669  default:
670  $hash = base64_encode(sha1($data, TRUE));
671  break;
672  }
673  $params['oauth_body_hash'] = $hash;
674  }
675 
676 // Add OAuth signature
677  switch ($this->signatureMethod) {
678  case 'HMAC-SHA224':
679  $hmacMethod = new OAuth\OAuthSignatureMethod_HMAC_SHA224();
680  break;
681  case 'HMAC-SHA256':
682  $hmacMethod = new OAuth\OAuthSignatureMethod_HMAC_SHA256();
683  break;
684  case 'HMAC-SHA384':
685  $hmacMethod = new OAuth\OAuthSignatureMethod_HMAC_SHA384();
686  break;
687  case 'HMAC-SHA512':
688  $hmacMethod = new OAuth\OAuthSignatureMethod_HMAC_SHA512();
689  break;
690  default:
691  $hmacMethod = new OAuth\OAuthSignatureMethod_HMAC_SHA1();
692  break;
693  }
694  $oauthConsumer = new OAuth\OAuthConsumer($this->key, $this->secret, null);
695  $oauthReq = OAuth\OAuthRequest::from_consumer_and_token($oauthConsumer, null, $method, $endpoint, $params);
696  $oauthReq->sign_request($hmacMethod, $oauthConsumer, null);
697  if (!is_array($data)) {
698  $header = $oauthReq->to_header();
699  if (empty($data)) {
700  if (!empty($type)) {
701  $header .= "\nAccept: {$type}";
702  }
703  } elseif (isset($type)) {
704  $header .= "\nContent-Type: {$type}";
705  $header .= "\nContent-Length: " . strlen($data);
706  }
707  return $header;
708  } else {
709  $params = $oauthReq->get_parameters();
710  foreach ($queryParams as $key => $value) {
711  if (!is_array($value)) {
712  if (!is_array($params[$key])) {
713  if ($params[$key] === $value) {
714  unset($params[$key]);
715  }
716  } else {
717  $params[$key] = array_diff($params[$key], array($value));
718  }
719  } else {
720  foreach ($value as $element) {
721  $params[$key] = array_diff($params[$key], array($value));
722  }
723  }
724  }
725  return $params;
726  }
727  }
728 
729 }
$lastAccess
Timestamp for date of last connection from this tool consumer.
Class to implement the Tool Settings service.
getIsAvailable()
Is the consumer key available to accept launch requests?
getSetting($name, $default='')
Get a setting value.
const ID_SCOPE_ID_ONLY
Use ID value only.
$updated
Timestamp for when the object was last updated.
$protected
Whether the tool consumer instance is protected by matching the consumer_guid value in incoming reque...
$consumerName
Name of tool consumer (as reported by last tool consumer connection).
Class to represent a tool consumer.
save()
Save the tool consumer to the database.
setRecordId($id)
Sets the tool consumer record ID.
static from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null)
pretty much a helper function to set up the request
$cssPath
Optional CSS path (as reported by last tool consumer connection).
static getDataConnector($db=null, $dbTableNamePrefix='', $type='')
Create data connector object.
getDataConnector()
Get the data connector.
$lastServiceRequest
HTTPMessage object for last service request.
$defaultEmail
Default email address (or email domain) to use when no email address is provided for a user.
$idScope
Default scope to use when generating an Id value for a user.
getToolSettings($simple=true)
Get Tool Settings.
initialize()
Initialise the tool consumer.
$enableUntil
Timestamp until which the tool consumer instance is enabled to accept incoming connection requests.
getRecordId()
Get the tool consumer record ID.
$enableFrom
Timestamp from which the the tool consumer instance is enabled to accept incoming connection requests...
signParameters($url, $type, $version, $params)
Add the signature to an LTI message.
$signatureMethod
Method used for signing messages.
getKey()
Get the tool consumer key.
doServiceRequest($service, $method, $format, $data)
Perform a service request.
$name
Local name of tool consumer.
$enabled
Whether the tool consumer instance is enabled to accept incoming connection requests.
saveSettings()
Save setting values.
getFamilyCode()
Get tool consumer family code (as reported by last tool consumer connection).
setKey($key)
Set the tool consumer key.
Class to represent an HTTP message request.
Definition: HTTPMessage.php:16
setSetting($name, $value=null)
Set a setting value.
addSignature($endpoint, $data, $method='POST', $type=null, $forTP=false)
Add the signature to an array of message parameters or to a header string.
__construct($key=null, $dataConnector=null, $autoEnable=false)
Class constructor.
getSettings()
Get an array of all setting values.
$profile
The consumer profile data.
static parse_parameters($input)
Definition: OAuthUtil.php:97
$created
Timestamp for when the object was created.
initialise()
Initialise the tool consumer.
signServiceRequest($url, $method, $type, $data=null)
Generates the headers for an LTI service request.
setToolSettings($settings=array())
Perform a Tool Settings service request.
static getRandomString($length=8)
Generate a random string.
$consumerGuid
Tool consumer GUID (as reported by first tool consumer connection).
$ltiVersion
LTI version (as reported by last tool consumer connection).
$consumerVersion
Tool consumer version (as reported by last tool consumer connection).
hasToolSettingsService()
Check if the Tool Settings service is supported.
static fromRecordId($id, $dataConnector)
Load the tool consumer from the database by its record ID.
setSettings($settings)
Set an array of all setting values.