LTI Integration Library  3.1.0
PHP class library for building LTI integrations
DataConnector_pdo.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use ceLTIc\LTI;
13 
23 {
24 
31  public function __construct($db, $dbTableNamePrefix = '')
32  {
33  parent::__construct($db, $dbTableNamePrefix);
34  }
35 
36 ###
37 ### ToolConsumer methods
38 ###
39 
47  public function loadToolConsumer($consumer)
48  {
49  $ok = false;
50  if (!is_null($consumer->getRecordId())) {
51  $sql = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .
52  'signature_method, consumer_name, consumer_version, consumer_guid, ' .
53  'profile, tool_proxy, settings, protected, enabled, ' .
54  'enable_from, enable_until, last_access, created, updated ' .
55  "FROM {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' ' .
56  'WHERE consumer_pk = :id';
57  $query = $this->db->prepare($sql);
58  $id = $consumer->getRecordId();
59  $query->bindValue('id', $id, \PDO::PARAM_INT);
60  } else {
61  $sql = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .
62  'signature_method, consumer_name, consumer_version, consumer_guid, ' .
63  'profile, tool_proxy, settings, protected, enabled, ' .
64  'enable_from, enable_until, last_access, created, updated ' .
65  "FROM {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' ' .
66  'WHERE consumer_key256 = :key256';
67  $query = $this->db->prepare($sql);
68  $key256 = static::getConsumerKey($consumer->getKey());
69  $query->bindValue('key256', $key256, \PDO::PARAM_STR);
70  }
71 
72  if ($query->execute()) {
73  while ($row = $query->fetch(\PDO::FETCH_ASSOC)) {
74  $row = array_change_key_case($row);
75  if (empty($key256) || empty($row['consumer_key']) || ($consumer->getKey() === $row['consumer_key'])) {
76  $consumer->setRecordId(intval($row['consumer_pk']));
77  $consumer->name = $row['name'];
78  $consumer->setkey(empty($row['consumer_key']) ? $row['consumer_key256'] : $row['consumer_key']);
79  $consumer->secret = $row['secret'];
80  $consumer->ltiVersion = $row['lti_version'];
81  $consumer->signatureMethod = $row['signature_method'];
82  $consumer->consumerName = $row['consumer_name'];
83  $consumer->consumerVersion = $row['consumer_version'];
84  $consumer->consumerGuid = $row['consumer_guid'];
85  $consumer->profile = json_decode($row['profile']);
86  $consumer->toolProxy = $row['tool_proxy'];
87  $settings = json_decode($row['settings'], TRUE);
88  if (!is_array($settings)) {
89  $settings = @unserialize($row['settings']); // check for old serialized setting
90  }
91  if (!is_array($settings)) {
92  $settings = array();
93  }
94  $consumer->setSettings($settings);
95  $consumer->protected = (intval($row['protected']) === 1);
96  $consumer->enabled = (intval($row['enabled']) === 1);
97  $consumer->enableFrom = null;
98  if (!is_null($row['enable_from'])) {
99  $consumer->enableFrom = strtotime($row['enable_from']);
100  }
101  $consumer->enableUntil = null;
102  if (!is_null($row['enable_until'])) {
103  $consumer->enableUntil = strtotime($row['enable_until']);
104  }
105  $consumer->lastAccess = null;
106  if (!is_null($row['last_access'])) {
107  $consumer->lastAccess = strtotime($row['last_access']);
108  }
109  $consumer->created = strtotime($row['created']);
110  $consumer->updated = strtotime($row['updated']);
111  $ok = true;
112  break;
113  }
114  }
115  }
116 
117  return $ok;
118  }
119 
127  public function saveToolConsumer($consumer)
128  {
129  $id = $consumer->getRecordId();
130  $key = $consumer->getKey();
131  $key256 = $this->getConsumerKey($key);
132  if ($key === $key256) {
133  $key = null;
134  }
135  $protected = ($consumer->protected) ? 1 : 0;
136  $enabled = ($consumer->enabled) ? 1 : 0;
137  $profile = (!empty($consumer->profile)) ? json_encode($consumer->profile) : null;
138  $settingsValue = json_encode($consumer->getSettings());
139  $time = time();
140  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
141  $from = null;
142  if (!is_null($consumer->enableFrom)) {
143  $from = date("{$this->dateFormat} {$this->timeFormat}", $consumer->enableFrom);
144  }
145  $until = null;
146  if (!is_null($consumer->enableUntil)) {
147  $until = date("{$this->dateFormat} {$this->timeFormat}", $consumer->enableUntil);
148  }
149  $last = null;
150  if (!is_null($consumer->lastAccess)) {
151  $last = date($this->dateFormat, $consumer->lastAccess);
152  }
153  if (empty($id)) {
154  $sql = "INSERT INTO {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' (consumer_key256, consumer_key, name, ' .
155  'secret, lti_version, signature_method, consumer_name, consumer_version, consumer_guid, profile, tool_proxy, settings, protected, enabled, ' .
156  'enable_from, enable_until, last_access, created, updated) ' .
157  'VALUES (:key256, :key, :name, :secret, :lti_version, :signature_method, :consumer_name, :consumer_version, :consumer_guid, :profile, :tool_proxy, :settings, ' .
158  ':protected, :enabled, :enable_from, :enable_until, :last_access, :created, :updated)';
159  $query = $this->db->prepare($sql);
160  $query->bindValue('key256', $key256, \PDO::PARAM_STR);
161  $query->bindValue('key', $key, \PDO::PARAM_STR);
162  $query->bindValue('name', $consumer->name, \PDO::PARAM_STR);
163  $query->bindValue('secret', $consumer->secret, \PDO::PARAM_STR);
164  $query->bindValue('lti_version', $consumer->ltiVersion, \PDO::PARAM_STR);
165  $query->bindValue('signature_method', $consumer->signatureMethod, \PDO::PARAM_STR);
166  $query->bindValue('consumer_name', $consumer->consumerName, \PDO::PARAM_STR);
167  $query->bindValue('consumer_version', $consumer->consumerVersion, \PDO::PARAM_STR);
168  $query->bindValue('consumer_guid', $consumer->consumerGuid, \PDO::PARAM_STR);
169  $query->bindValue('profile', $profile, \PDO::PARAM_STR);
170  $query->bindValue('tool_proxy', $consumer->toolProxy, \PDO::PARAM_STR);
171  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
172  $query->bindValue('protected', $protected, \PDO::PARAM_INT);
173  $query->bindValue('enabled', $enabled, \PDO::PARAM_INT);
174  $query->bindValue('enable_from', $from, \PDO::PARAM_STR);
175  $query->bindValue('enable_until', $until, \PDO::PARAM_STR);
176  $query->bindValue('last_access', $last, \PDO::PARAM_STR);
177  $query->bindValue('created', $now, \PDO::PARAM_STR);
178  $query->bindValue('updated', $now, \PDO::PARAM_STR);
179  } else {
180  $sql = 'UPDATE ' . $this->dbTableNamePrefix . static::CONSUMER_TABLE_NAME . ' ' .
181  'SET consumer_key256 = :key256, consumer_key = :key, name = :name, secret = :secret, lti_version = :lti_version, ' .
182  'signature_method = :signature_method, consumer_name = :consumer_name, ' .
183  'consumer_version = :consumer_version, consumer_guid = :consumer_guid, ' .
184  'profile = :profile, tool_proxy = :tool_proxy, settings = :settings, ' .
185  'protected = :protected, enabled = :enabled, enable_from = :enable_from, enable_until = :enable_until, last_access = :last_access, updated = :updated ' .
186  'WHERE consumer_pk = :id';
187  $query = $this->db->prepare($sql);
188  $query->bindValue('key256', $key256, \PDO::PARAM_STR);
189  $query->bindValue('key', $key, \PDO::PARAM_STR);
190  $query->bindValue('name', $consumer->name, \PDO::PARAM_STR);
191  $query->bindValue('secret', $consumer->secret, \PDO::PARAM_STR);
192  $query->bindValue('lti_version', $consumer->ltiVersion, \PDO::PARAM_STR);
193  $query->bindValue('signature_method', $consumer->signatureMethod, \PDO::PARAM_STR);
194  $query->bindValue('consumer_name', $consumer->consumerName, \PDO::PARAM_STR);
195  $query->bindValue('consumer_version', $consumer->consumerVersion, \PDO::PARAM_STR);
196  $query->bindValue('consumer_guid', $consumer->consumerGuid, \PDO::PARAM_STR);
197  $query->bindValue('profile', $profile, \PDO::PARAM_STR);
198  $query->bindValue('tool_proxy', $consumer->toolProxy, \PDO::PARAM_STR);
199  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
200  $query->bindValue('protected', $protected, \PDO::PARAM_INT);
201  $query->bindValue('enabled', $enabled, \PDO::PARAM_INT);
202  $query->bindValue('enable_from', $from, \PDO::PARAM_STR);
203  $query->bindValue('enable_until', $until, \PDO::PARAM_STR);
204  $query->bindValue('last_access', $last, \PDO::PARAM_STR);
205  $query->bindValue('updated', $now, \PDO::PARAM_STR);
206  $query->bindValue('id', $id, \PDO::PARAM_INT);
207  }
208  $ok = $query->execute();
209  if ($ok) {
210  if (empty($id)) {
211  $consumer->setRecordId($this->getLastInsertId(static::CONSUMER_TABLE_NAME));
212  $consumer->created = $time;
213  }
214  $consumer->updated = $time;
215  }
216 
217  return $ok;
218  }
219 
227  public function deleteToolConsumer0($consumer)
228  {
229  $id = $consumer->getRecordId();
230 
231 // Delete any nonce values for this consumer
232  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE consumer_pk = :id';
233  $query = $this->db->prepare($sql);
234  $query->bindValue('id', $id, \PDO::PARAM_INT);
235  $query->execute();
236 
237 // Delete any outstanding share keys for resource links for this consumer
238  $sql = 'DELETE sk ' .
239  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
240  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
241  'WHERE rl.consumer_pk = :id';
242  $query = $this->db->prepare($sql);
243  $query->bindValue('id', $id, \PDO::PARAM_INT);
244  $query->execute();
245 
246 // Delete any outstanding share keys for resource links for contexts in this consumer
247  $sql = 'DELETE sk ' .
248  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
249  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
250  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
251  'WHERE c.consumer_pk = :id';
252  $query = $this->db->prepare($sql);
253  $query->bindValue('id', $id, \PDO::PARAM_INT);
254  $query->execute();
255 
256 // Delete any users in resource links for this consumer
257  $sql = 'DELETE u ' .
258  "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
259  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
260  'WHERE rl.consumer_pk = :id';
261  $query = $this->db->prepare($sql);
262  $query->bindValue('id', $id, \PDO::PARAM_INT);
263  $query->execute();
264 
265 // Delete any users in resource links for contexts in this consumer
266  $sql = 'DELETE u ' .
267  "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
268  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
269  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
270  'WHERE c.consumer_pk = :id';
271  $query = $this->db->prepare($sql);
272  $query->bindValue('id', $id, \PDO::PARAM_INT);
273  $query->execute();
274 
275 // Update any resource links for which this consumer is acting as a primary resource link
276  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' prl ' .
277  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
278  'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .
279  'WHERE rl.consumer_pk = :id';
280  $query = $this->db->prepare($sql);
281  $query->bindValue('id', $id, \PDO::PARAM_INT);
282  $query->execute();
283 
284 // Update any resource links for contexts in which this consumer is acting as a primary resource link
285  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' prl ' .
286  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
287  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
288  'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .
289  'WHERE c.consumer_pk = :id';
290  $query = $this->db->prepare($sql);
291  $query->bindValue('id', $id, \PDO::PARAM_INT);
292  $query->execute();
293 
294 // Delete any resource links for this consumer
295  $sql = 'DELETE rl ' .
296  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
297  'WHERE rl.consumer_pk = :id';
298  $query = $this->db->prepare($sql);
299  $query->bindValue('id', $id, \PDO::PARAM_INT);
300  $query->execute();
301 
302 // Delete any resource links for contexts in this consumer
303  $sql = 'DELETE rl ' .
304  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
305  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
306  'WHERE c.consumer_pk = :id';
307  $query = $this->db->prepare($sql);
308  $query->bindValue('id', $id, \PDO::PARAM_INT);
309  $query->execute();
310 
311 // Delete any contexts for this consumer
312  $sql = 'DELETE c ' .
313  "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ' .
314  'WHERE c.consumer_pk = :id';
315  $query = $this->db->prepare($sql);
316  $query->bindValue('id', $id, \PDO::PARAM_INT);
317  $query->execute();
318 
319 // Delete consumer
320  $sql = 'DELETE c ' .
321  "FROM {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' c ' .
322  'WHERE c.consumer_pk = :id';
323  $query = $this->db->prepare($sql);
324  $query->bindValue('id', $id, \PDO::PARAM_INT);
325  $ok = $query->execute();
326 
327  if ($ok) {
328  $consumer->initialize();
329  }
330 
331  return $ok;
332  }
333 
334  public function deleteToolConsumer($consumer)
335  {
336  $id = $consumer->getRecordId();
337 
338 // Delete any nonce values for this consumer
339  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE consumer_pk = :id';
340  $query = $this->db->prepare($sql);
341  $query->bindValue('id', $id, \PDO::PARAM_INT);
342  $query->execute();
343 
344 // Delete any outstanding share keys for resource links for this consumer
345  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
346  "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
347  'WHERE consumer_pk = :id)';
348  $query = $this->db->prepare($sql);
349  $query->bindValue('id', $id, \PDO::PARAM_INT);
350  $query->execute();
351 
352 // Delete any outstanding share keys for resource links for contexts in this consumer
353  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
354  "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
355  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk WHERE c.consumer_pk = :id)';
356  $query = $this->db->prepare($sql);
357  $query->bindValue('id', $id, \PDO::PARAM_INT);
358  $query->execute();
359 
360 // Delete any users in resource links for this consumer
361  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
362  "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
363  'WHERE consumer_pk = :id)';
364  $query = $this->db->prepare($sql);
365  $query->bindValue('id', $id, \PDO::PARAM_INT);
366  $query->execute();
367 
368 // Delete any users in resource links for contexts in this consumer
369  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
370  "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
371  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk WHERE c.consumer_pk = :id)';
372  $query = $this->db->prepare($sql);
373  $query->bindValue('id', $id, \PDO::PARAM_INT);
374  $query->execute();
375 
376 // Update any resource links for which this consumer is acting as a primary resource link
377  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
378  'SET primary_resource_link_pk = NULL, share_approved = NULL ' .
379  'WHERE primary_resource_link_pk IN ' .
380  "(SELECT resource_link_pk FROM (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
381  'WHERE consumer_pk = :id) t)';
382  $query = $this->db->prepare($sql);
383  $query->bindValue('id', $id, \PDO::PARAM_INT);
384  $query->execute();
385 
386 // Update any resource links for contexts in which this consumer is acting as a primary resource link
387  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
388  'SET primary_resource_link_pk = NULL, share_approved = NULL ' .
389  'WHERE primary_resource_link_pk IN ' .
390  "(SELECT resource_link_pk FROM (SELECT rl.resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
391  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
392  'WHERE c.consumer_pk = :id) t)';
393  $query = $this->db->prepare($sql);
394  $query->bindValue('id', $id, \PDO::PARAM_INT);
395  $query->execute();
396 
397 // Delete any resource links for this consumer
398  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
399  'WHERE consumer_pk = :id';
400  $query = $this->db->prepare($sql);
401  $query->bindValue('id', $id, \PDO::PARAM_INT);
402  $query->execute();
403 
404 // Delete any resource links for contexts in this consumer
405  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
406  'WHERE context_pk IN (' .
407  "SELECT context_pk FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' . 'WHERE consumer_pk = :id)';
408  $query = $this->db->prepare($sql);
409  $query->bindValue('id', $id, \PDO::PARAM_INT);
410  $query->execute();
411 
412 // Delete any contexts for this consumer
413  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
414  'WHERE consumer_pk = :id';
415  $query = $this->db->prepare($sql);
416  $query->bindValue('id', $id, \PDO::PARAM_INT);
417  $query->execute();
418 
419 // Delete consumer
420  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' ' .
421  'WHERE consumer_pk = :id';
422  $query = $this->db->prepare($sql);
423  $query->bindValue('id', $id, \PDO::PARAM_INT);
424  $ok = $query->execute();
425 
426  if ($ok) {
427  $consumer->initialize();
428  }
429 
430  return $ok;
431  }
432 
438  public function getToolConsumers()
439  {
440  $consumers = array();
441 
442  $sql = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .
443  'signature_method, consumer_name, consumer_version, consumer_guid, ' .
444  'profile, tool_proxy, settings, protected, enabled, ' .
445  'enable_from, enable_until, last_access, created, updated ' .
446  "FROM {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' ' .
447  'ORDER BY name';
448  $query = $this->db->prepare($sql);
449  $ok = ($query !== FALSE);
450 
451  if ($ok) {
452  $ok = $query->execute();
453  }
454 
455  if ($ok) {
456  while ($row = $query->fetch(\PDO::FETCH_ASSOC)) {
457  $row = array_change_key_case($row);
458  $key = empty($row['consumer_key']) ? $row['consumer_key256'] : $row['consumer_key'];
459  $consumer = new LTI\ToolConsumer($key, $this);
460  $consumer->setRecordId(intval($row['consumer_pk']));
461  $consumer->name = $row['name'];
462  $consumer->secret = $row['secret'];
463  $consumer->ltiVersion = $row['lti_version'];
464  $consumer->signatureMethod = $row['signature_method'];
465  $consumer->consumerName = $row['consumer_name'];
466  $consumer->consumerVersion = $row['consumer_version'];
467  $consumer->consumerGuid = $row['consumer_guid'];
468  $consumer->profile = json_decode($row['profile']);
469  $consumer->toolProxy = $row['tool_proxy'];
470  $settings = json_decode($row['settings'], TRUE);
471  if (!is_array($settings)) {
472  $settings = @unserialize($row['settings']); // check for old serialized setting
473  }
474  if (!is_array($settings)) {
475  $settings = array();
476  }
477  $consumer->setSettings($settings);
478  $consumer->protected = (intval($row['protected']) === 1);
479  $consumer->enabled = (intval($row['enabled']) === 1);
480  $consumer->enableFrom = null;
481  if (!is_null($row['enable_from'])) {
482  $consumer->enableFrom = strtotime($row['enable_from']);
483  }
484  $consumer->enableUntil = null;
485  if (!is_null($row['enable_until'])) {
486  $consumer->enableUntil = strtotime($row['enable_until']);
487  }
488  $consumer->lastAccess = null;
489  if (!is_null($row['last_access'])) {
490  $consumer->lastAccess = strtotime($row['last_access']);
491  }
492  $consumer->created = strtotime($row['created']);
493  $consumer->updated = strtotime($row['updated']);
494  $consumers[] = $consumer;
495  }
496  }
497 
498  return $consumers;
499  }
500 
501 ###
502 ### Context methods
503 ###
504 
512  public function loadContext($context)
513  {
514  $ok = false;
515  if (!is_null($context->getRecordId())) {
516  $sql = 'SELECT context_pk, consumer_pk, title, lti_context_id, type, settings, created, updated ' .
517  "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
518  'WHERE (context_pk = :id)';
519  $query = $this->db->prepare($sql);
520  $query->bindValue('id', $context->getRecordId(), \PDO::PARAM_INT);
521  } else {
522  $sql = 'SELECT context_pk, consumer_pk, title, lti_context_id, type, settings, created, updated ' .
523  "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
524  'WHERE (consumer_pk = :cid) AND (lti_context_id = :ctx)';
525  $query = $this->db->prepare($sql);
526  $query->bindValue('cid', $context->getConsumer()->getRecordId(), \PDO::PARAM_INT);
527  $query->bindValue('ctx', $context->ltiContextId, \PDO::PARAM_STR);
528  }
529  $ok = $query->execute();
530  if ($ok) {
531  $row = $query->fetch(\PDO::FETCH_ASSOC);
532  $ok = ($row !== FALSE);
533  }
534  if ($ok) {
535  $row = array_change_key_case($row);
536  $context->setRecordId(intval($row['context_pk']));
537  $context->setConsumerId(intval($row['consumer_pk']));
538  $context->title = $row['title'];
539  $context->ltiContextId = $row['lti_context_id'];
540  $context->type = $row['type'];
541  $settings = json_decode($row['settings'], TRUE);
542  if (!is_array($settings)) {
543  $settings = @unserialize($row['settings']); // check for old serialized setting
544  }
545  if (!is_array($settings)) {
546  $settings = array();
547  }
548  $context->setSettings($settings);
549  $context->created = strtotime($row['created']);
550  $context->updated = strtotime($row['updated']);
551  }
552 
553  return $ok;
554  }
555 
563  public function saveContext($context)
564  {
565  $time = time();
566  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
567  $settingsValue = json_encode($context->getSettings());
568  $id = $context->getRecordId();
569  $consumer_pk = $context->getConsumer()->getRecordId();
570  if (empty($id)) {
571  $sql = "INSERT INTO {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' (consumer_pk, title, ' .
572  'lti_context_id, type, settings, created, updated) ' .
573  'VALUES (:cid, :title, :ctx, :type, :settings, :created, :updated)';
574  $query = $this->db->prepare($sql);
575  $query->bindValue('cid', $consumer_pk, \PDO::PARAM_INT);
576  $query->bindValue('title', $context->title, \PDO::PARAM_STR);
577  $query->bindValue('ctx', $context->ltiContextId, \PDO::PARAM_STR);
578  $query->bindValue('type', $context->type, \PDO::PARAM_STR);
579  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
580  $query->bindValue('created', $now, \PDO::PARAM_STR);
581  $query->bindValue('updated', $now, \PDO::PARAM_STR);
582  } else {
583  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' SET ' .
584  'title = :title, lti_context_id = :ctx, type = :type, settings = :settings, ' .
585  'updated = :updated ' .
586  'WHERE (consumer_pk = :cid) AND (context_pk = :ctxid)';
587  $query = $this->db->prepare($sql);
588  $query->bindValue('title', $context->title, \PDO::PARAM_STR);
589  $query->bindValue('ctx', $context->ltiContextId, \PDO::PARAM_STR);
590  $query->bindValue('type', $context->type, \PDO::PARAM_STR);
591  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
592  $query->bindValue('updated', $now, \PDO::PARAM_STR);
593  $query->bindValue('cid', $consumer_pk, \PDO::PARAM_INT);
594  $query->bindValue('ctxid', $id, \PDO::PARAM_INT);
595  }
596  $ok = $query->execute();
597  if ($ok) {
598  if (empty($id)) {
599  $context->setRecordId($this->getLastInsertId(static::CONTEXT_TABLE_NAME));
600  $context->created = $time;
601  }
602  $context->updated = $time;
603  }
604 
605  return $ok;
606  }
607 
608  public function deleteContext($context)
609  {
610  $id = $context->getRecordId();
611 
612 // Delete any outstanding share keys for resource links for this context
613  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
614  "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
615  'WHERE context_pk = :id)';
616  $query = $this->db->prepare($sql);
617  $query->bindValue('id', $id, \PDO::PARAM_INT);
618  $query->execute();
619 
620 // Delete any users in resource links for this context
621  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
622  "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
623  'WHERE context_pk = :id)';
624  $query = $this->db->prepare($sql);
625  $query->bindValue('id', $id, \PDO::PARAM_INT);
626  $query->execute();
627 
628 // Update any resource links for which this consumer is acting as a primary resource link
629  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
630  'SET primary_resource_link_pk = null, share_approved = null ' .
631  'WHERE primary_resource_link_pk IN ' .
632  "(SELECT resource_link_pk FROM (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' WHERE context_pk = :id) t)';
633  $query = $this->db->prepare($sql);
634  $query->bindValue('id', $id, \PDO::PARAM_INT);
635  $query->execute();
636 
637 // Delete any resource links for this consumer
638  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
639  'WHERE context_pk = :id';
640  $query = $this->db->prepare($sql);
641  $query->bindValue('id', $id, \PDO::PARAM_INT);
642  $query->execute();
643 
644 // Delete context
645  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
646  'WHERE context_pk = :id';
647  $query = $this->db->prepare($sql);
648  $query->bindValue('id', $id, \PDO::PARAM_INT);
649  $ok = $query->execute();
650 
651  if ($ok) {
652  $context->initialize();
653  }
654 
655  return $ok;
656  }
657 
658 ###
659 ### ResourceLink methods
660 ###
661 
669  public function loadResourceLink($resourceLink)
670  {
671  if (!is_null($resourceLink->getRecordId())) {
672  $sql = 'SELECT resource_link_pk, context_pk, consumer_pk, title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' .
673  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
674  'WHERE (resource_link_pk = :id)';
675  $query = $this->db->prepare($sql);
676  $query->bindValue('id', $resourceLink->getRecordId(), \PDO::PARAM_INT);
677  } elseif (!is_null($resourceLink->getContext())) {
678  $sql = 'SELECT resource_link_pk, context_pk, consumer_pk, title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' .
679  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
680  'WHERE (context_pk = :id) AND (lti_resource_link_id = :rlid)';
681  $query = $this->db->prepare($sql);
682  $query->bindValue('id', $resourceLink->getContext()->getRecordId(), \PDO::PARAM_INT);
683  $query->bindValue('rlid', $resourceLink->getId(), \PDO::PARAM_STR);
684  } else {
685  $sql = 'SELECT r.resource_link_pk, r.context_pk, r.consumer_pk, r.title, r.lti_resource_link_id, r.settings, r.primary_resource_link_pk, r.share_approved, r.created, r.updated ' .
686  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r LEFT OUTER JOIN ' .
687  $this->dbTableNamePrefix . static::CONTEXT_TABLE_NAME . ' c ON r.context_pk = c.context_pk ' .
688  ' WHERE ((r.consumer_pk = :id1) OR (c.consumer_pk = :id2)) AND (lti_resource_link_id = :rlid)';
689  $query = $this->db->prepare($sql);
690  $query->bindValue('id1', $resourceLink->getConsumer()->getRecordId(), \PDO::PARAM_INT);
691  $query->bindValue('id2', $resourceLink->getConsumer()->getRecordId(), \PDO::PARAM_INT);
692  $query->bindValue('rlid', $resourceLink->getId(), \PDO::PARAM_STR);
693  }
694  $ok = $query->execute();
695  if ($ok) {
696  $row = $query->fetch(\PDO::FETCH_ASSOC);
697  $ok = ($row !== FALSE);
698  }
699 
700  if ($ok) {
701  $row = array_change_key_case($row);
702  $resourceLink->setRecordId(intval($row['resource_link_pk']));
703  if (!is_null($row['context_pk'])) {
704  $resourceLink->setContextId(intval($row['context_pk']));
705  } else {
706  $resourceLink->setContextId(null);
707  }
708  if (!is_null($row['consumer_pk'])) {
709  $resourceLink->setConsumerId(intval($row['consumer_pk']));
710  } else {
711  $resourceLink->setConsumerId(null);
712  }
713  $resourceLink->title = $row['title'];
714  $resourceLink->ltiResourceLinkId = $row['lti_resource_link_id'];
715  $settings = json_decode($row['settings'], TRUE);
716  if (!is_array($settings)) {
717  $settings = @unserialize($row['settings']); // check for old serialized setting
718  }
719  if (!is_array($settings)) {
720  $settings = array();
721  }
722  $resourceLink->setSettings($settings);
723  if (!is_null($row['primary_resource_link_pk'])) {
724  $resourceLink->primaryResourceLinkId = intval($row['primary_resource_link_pk']);
725  } else {
726  $resourceLink->primaryResourceLinkId = null;
727  }
728  $resourceLink->shareApproved = (is_null($row['share_approved'])) ? null : (intval($row['share_approved']) === 1);
729  $resourceLink->created = strtotime($row['created']);
730  $resourceLink->updated = strtotime($row['updated']);
731  }
732 
733  return $ok;
734  }
735 
743  public function saveResourceLink($resourceLink)
744  {
745  $time = time();
746  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
747  $settingsValue = json_encode($resourceLink->getSettings());
748  if (!is_null($resourceLink->getContext())) {
749  $consumerId = null;
750  $contextId = strval($resourceLink->getContext()->getRecordId());
751  } elseif (!is_null($resourceLink->getContextId())) {
752  $consumerId = null;
753  $contextId = strval($resourceLink->getContextId());
754  } else {
755  $consumerId = strval($resourceLink->getConsumer()->getRecordId());
756  $contextId = null;
757  }
758  if (empty($resourceLink->primaryResourceLinkId)) {
759  $primaryResourceLinkId = null;
760  } else {
761  $primaryResourceLinkId = $resourceLink->primaryResourceLinkId;
762  }
763  $id = $resourceLink->getRecordId();
764  if (empty($id)) {
765  $sql = "INSERT INTO {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' (consumer_pk, context_pk, ' .
766  'title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated) ' .
767  'VALUES (:cid, :ctx, :title, :rlid, :settings, :prlid, :share_approved, :created, :updated)';
768  $query = $this->db->prepare($sql);
769  $query->bindValue('cid', $consumerId, \PDO::PARAM_INT);
770  $query->bindValue('ctx', $contextId, \PDO::PARAM_INT);
771  $query->bindValue('title', $resourceLink->title, \PDO::PARAM_STR);
772  $query->bindValue('rlid', $resourceLink->getId(), \PDO::PARAM_STR);
773  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
774  $query->bindValue('prlid', $primaryResourceLinkId, \PDO::PARAM_INT);
775  $query->bindValue('share_approved', $resourceLink->shareApproved, \PDO::PARAM_INT);
776  $query->bindValue('created', $now, \PDO::PARAM_STR);
777  $query->bindValue('updated', $now, \PDO::PARAM_STR);
778  } elseif (!is_null($contextId)) {
779  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' SET ' .
780  'consumer_pk = NULL, context_pk = :ctx, title = :title, lti_resource_link_id = :rlid, settings = :settings, ' .
781  'primary_resource_link_pk = :prlid, share_approved = :share_approved, updated = :updated ' .
782  'WHERE (resource_link_pk = :id)';
783  $query = $this->db->prepare($sql);
784  $query->bindValue('ctx', $contextId, \PDO::PARAM_INT);
785  $query->bindValue('title', $resourceLink->title, \PDO::PARAM_STR);
786  $query->bindValue('rlid', $resourceLink->getId(), \PDO::PARAM_STR);
787  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
788  $query->bindValue('prlid', $primaryResourceLinkId, \PDO::PARAM_INT);
789  $query->bindValue('share_approved', $resourceLink->shareApproved, \PDO::PARAM_INT);
790  $query->bindValue('updated', $now, \PDO::PARAM_STR);
791  $query->bindValue('id', $id, \PDO::PARAM_INT);
792  } else {
793  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' SET ' .
794  'context_pk = :ctx, title = :title, lti_resource_link_id = :rlid, settings = :settings, ' .
795  'primary_resource_link_pk = :prlid, share_approved = :share_approved, updated = :updated ' .
796  'WHERE (consumer_pk = :cid) AND (resource_link_pk = :id)';
797  $query = $this->db->prepare($sql);
798  $query->bindValue('ctx', $contextId, \PDO::PARAM_INT);
799  $query->bindValue('title', $resourceLink->title, \PDO::PARAM_STR);
800  $query->bindValue('rlid', $resourceLink->getId(), \PDO::PARAM_STR);
801  $query->bindValue('settings', $settingsValue, \PDO::PARAM_STR);
802  $query->bindValue('prlid', $primaryResourceLinkId, \PDO::PARAM_INT);
803  $query->bindValue('share_approved', $resourceLink->shareApproved, \PDO::PARAM_INT);
804  $query->bindValue('updated', $now, \PDO::PARAM_STR);
805  $query->bindValue('cid', $consumerId, \PDO::PARAM_INT);
806  $query->bindValue('id', $id, \PDO::PARAM_INT);
807  }
808  $ok = $query->execute();
809  if ($ok) {
810  if (empty($id)) {
811  $resourceLink->setRecordId($this->getLastInsertId(static::RESOURCE_LINK_TABLE_NAME));
812  $resourceLink->created = $time;
813  }
814  $resourceLink->updated = $time;
815  }
816 
817  return $ok;
818  }
819 
827  public function deleteResourceLink($resourceLink)
828  {
829  $id = $resourceLink->getRecordId();
830 
831 // Delete any outstanding share keys for resource links for this consumer
832  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
833  'WHERE (resource_link_pk = :id)';
834  $query = $this->db->prepare($sql);
835  $query->bindValue('id', $id, \PDO::PARAM_INT);
836  $ok = $query->execute();
837 
838 // Delete users
839  if ($ok) {
840  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
841  'WHERE (resource_link_pk = :id)';
842  $query = $this->db->prepare($sql);
843  $query->bindValue('id', $id, \PDO::PARAM_INT);
844  $ok = $query->execute();
845  }
846 
847 // Update any resource links for which this is the primary resource link
848  if ($ok) {
849  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
850  'SET primary_resource_link_pk = NULL ' .
851  'WHERE (primary_resource_link_pk = :id)';
852  $query = $this->db->prepare($sql);
853  $query->bindValue('id', $id, \PDO::PARAM_INT);
854  $ok = $query->execute();
855  }
856 
857 // Delete resource link
858  if ($ok) {
859  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
860  'WHERE (resource_link_pk = :id)';
861  $query = $this->db->prepare($sql);
862  $query->bindValue('id', $id, \PDO::PARAM_INT);
863  $ok = $query->execute();
864  }
865 
866  if ($ok) {
867  $resourceLink->initialize();
868  }
869 
870  return $ok;
871  }
872 
885  public function getUserResultSourcedIDsResourceLink($resourceLink, $localOnly, $idScope)
886  {
887  $id = $resourceLink->getRecordId();
888  $userResults = array();
889 
890  if ($localOnly) {
891  $sql = 'SELECT u.user_result_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
892  "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
893  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
894  'ON u.resource_link_pk = rl.resource_link_pk ' .
895  'WHERE (rl.resource_link_pk = :id) AND (rl.primary_resource_link_pk IS NULL)';
896  $query = $this->db->prepare($sql);
897  $query->bindValue('id', $id, \PDO::PARAM_INT);
898  } else {
899  $sql = 'SELECT u.user_result_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
900  "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
901  "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
902  'ON u.resource_link_pk = rl.resource_link_pk ' .
903  'WHERE ((rl.resource_link_pk = :id) AND (rl.primary_resource_link_pk IS NULL)) OR ' .
904  '((rl.primary_resource_link_pk = :pid) AND (share_approved = 1))';
905  $query = $this->db->prepare($sql);
906  $query->bindValue('id', $id, \PDO::PARAM_INT);
907  $query->bindValue('pid', $id, \PDO::PARAM_INT);
908  }
909  if ($query->execute()) {
910  while ($row = $query->fetch(\PDO::FETCH_ASSOC)) {
911  $row = array_change_key_case($row);
912  $userresult = LTI\UserResult::fromRecordId($row['user_result_pk'], $resourceLink->getDataConnector());
913  $userresult->setRecordId(intval($row['user_result_pk']));
914  $userresult->ltiResultSourcedId = $row['lti_result_sourcedid'];
915  $userresult->created = strtotime($row['created']);
916  $userresult->updated = strtotime($row['updated']);
917  if (is_null($idScope)) {
918  $userResults[] = $userresult;
919  } else {
920  $userResults[$userresult->getId($idScope)] = $userresult;
921  }
922  }
923  }
924 
925  return $userResults;
926  }
927 
935  public function getSharesResourceLink($resourceLink)
936  {
937  $id = $resourceLink->getRecordId();
938 
939  $shares = array();
940 
941  $sql = 'SELECT c.consumer_name, r.resource_link_pk, r.title, r.share_approved ' .
942  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r ' .
943  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' c ON r.consumer_pk = c.consumer_pk ' .
944  'WHERE (r.primary_resource_link_pk = :id1) ' .
945  'UNION ' .
946  'SELECT c2.consumer_name, r2.resource_link_pk, r2.title, r2.share_approved ' .
947  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r2 ' .
948  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' x ON r2.context_pk = x.context_pk ' .
949  "INNER JOIN {$this->dbTableNamePrefix}" . static::CONSUMER_TABLE_NAME . ' c2 ON x.consumer_pk = c2.consumer_pk ' .
950  'WHERE (r2.primary_resource_link_pk = :id2) ' .
951  'ORDER BY consumer_name, title';
952  $query = $this->db->prepare($sql);
953  $query->bindValue('id1', $id, \PDO::PARAM_INT);
954  $query->bindValue('id2', $id, \PDO::PARAM_INT);
955  if ($query->execute()) {
956  while ($row = $query->fetch(\PDO::FETCH_ASSOC)) {
957  $row = array_change_key_case($row);
958  $share = new LTI\ResourceLinkShare();
959  $share->resourceLinkId = intval($row['resource_link_pk']);
960  $share->approved = (intval($row['share_approved']) === 1);
961  $shares[] = $share;
962  }
963  }
964 
965  return $shares;
966  }
967 
968 ###
969 ### ConsumerNonce methods
970 ###
971 
979  public function loadConsumerNonce($nonce)
980  {
981 // Delete any expired nonce values
982  $now = date("{$this->dateFormat} {$this->timeFormat}", time());
983  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE expires <= :now';
984  $query = $this->db->prepare($sql);
985  $query->bindValue('now', $now, \PDO::PARAM_STR);
986  $query->execute();
987 
988 // Load the nonce
989  $id = $nonce->getConsumer()->getRecordId();
990  $value = $nonce->getValue();
991  $sql = "SELECT value T FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE (consumer_pk = :id) AND (value = :value)';
992  $query = $this->db->prepare($sql);
993  $query->bindValue('id', $id, \PDO::PARAM_INT);
994  $query->bindValue('value', $value, \PDO::PARAM_STR);
995  $ok = $query->execute();
996  if ($ok) {
997  $row = $query->fetch(\PDO::FETCH_ASSOC);
998  if ($row === false) {
999  $ok = false;
1000  }
1001  }
1002 
1003  return $ok;
1004  }
1005 
1013  public function saveConsumerNonce($nonce)
1014  {
1015  $id = $nonce->getConsumer()->getRecordId();
1016  $value = $nonce->getValue();
1017  $expires = date("{$this->dateFormat} {$this->timeFormat}", $nonce->expires);
1018  $sql = "INSERT INTO {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' (consumer_pk, value, expires) VALUES (:id, :value, :expires)';
1019  $query = $this->db->prepare($sql);
1020  $query->bindValue('id', $id, \PDO::PARAM_INT);
1021  $query->bindValue('value', $value, \PDO::PARAM_STR);
1022  $query->bindValue('expires', $expires, \PDO::PARAM_STR);
1023  $ok = $query->execute();
1024 
1025  return $ok;
1026  }
1027 
1028 ###
1029 ### ResourceLinkShareKey methods
1030 ###
1031 
1039  public function loadResourceLinkShareKey($shareKey)
1040  {
1041  $ok = false;
1042 
1043 // Clear expired share keys
1044  $now = date("{$this->dateFormat} {$this->timeFormat}", time());
1045  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' WHERE expires <= :now';
1046  $query = $this->db->prepare($sql);
1047  $query->bindValue('now', $now, \PDO::PARAM_STR);
1048  $query->execute();
1049 
1050 // Load share key
1051  $id = $shareKey->getId();
1052  $sql = 'SELECT resource_link_pk, auto_approve, expires ' .
1053  "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
1054  'WHERE share_key_id = :id';
1055  $query = $this->db->prepare($sql);
1056  $query->bindValue('id', $id, \PDO::PARAM_STR);
1057  if ($query->execute()) {
1058  $row = $query->fetch(\PDO::FETCH_ASSOC);
1059  if ($row !== FALSE) {
1060  $row = array_change_key_case($row);
1061  if (intval($row['resource_link_pk']) === $shareKey->resourceLinkId) {
1062  $shareKey->autoApprove = ($row['auto_approve'] === 1);
1063  $shareKey->expires = strtotime($row['expires']);
1064  $ok = true;
1065  }
1066  }
1067  }
1068 
1069  return $ok;
1070  }
1071 
1079  public function saveResourceLinkShareKey($shareKey)
1080  {
1081  $id = $shareKey->getId();
1082  $expires = date("{$this->dateFormat} {$this->timeFormat}", $shareKey->expires);
1083  $sql = "INSERT INTO {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
1084  '(share_key_id, resource_link_pk, auto_approve, expires) ' .
1085  'VALUES (:id, :prlid, :approve, :expires)';
1086  $query = $this->db->prepare($sql);
1087  $query->bindValue('id', $id, \PDO::PARAM_STR);
1088  $query->bindValue('prlid', $shareKey->resourceLinkId, \PDO::PARAM_INT);
1089  $query->bindValue('approve', $shareKey->autoApprove, \PDO::PARAM_INT);
1090  $query->bindValue('expires', $expires, \PDO::PARAM_STR);
1091  $ok = $query->execute();
1092 
1093  return $ok;
1094  }
1095 
1103  public function deleteResourceLinkShareKey($shareKey)
1104  {
1105  $id = $shareKey->getId();
1106  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' WHERE share_key_id = :id';
1107  $query = $this->db->prepare($sql);
1108  $query->bindValue('id', $id, \PDO::PARAM_STR);
1109  $ok = $query->execute();
1110 
1111  if ($ok) {
1112  $shareKey->initialize();
1113  }
1114 
1115  return $ok;
1116  }
1117 
1118 ###
1119 ### UserResult Result methods
1120 ###
1121 
1129  public function loadUserResult($userresult)
1130  {
1131  $ok = false;
1132  if (!is_null($userresult->getRecordId())) {
1133  $id = $userresult->getRecordId();
1134  $sql = 'SELECT user_result_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1135  "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1136  'WHERE (user_result_pk = :id)';
1137  $query = $this->db->prepare($sql);
1138  $query->bindValue('id', $id, \PDO::PARAM_INT);
1139  } else {
1140  $id = $userresult->getResourceLink()->getRecordId();
1141  $uid = $userresult->getId(LTI\ToolProvider::ID_SCOPE_ID_ONLY);
1142  $sql = 'SELECT user_result_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1143  "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1144  'WHERE (resource_link_pk = :id) AND (lti_user_id = :u_id)';
1145  $query = $this->db->prepare($sql);
1146  $query->bindValue('id', $id, \PDO::PARAM_INT);
1147  $query->bindValue('u_id', $uid, \PDO::PARAM_STR);
1148  }
1149  if ($query->execute()) {
1150  $row = $query->fetch(\PDO::FETCH_ASSOC);
1151  if ($row !== false) {
1152  $row = array_change_key_case($row);
1153  $userresult->setRecordId(intval($row['user_result_pk']));
1154  $userresult->setResourceLinkId(intval($row['resource_link_pk']));
1155  $userresult->ltiUserId = $row['lti_user_id'];
1156  $userresult->ltiResultSourcedId = $row['lti_result_sourcedid'];
1157  $userresult->created = strtotime($row['created']);
1158  $userresult->updated = strtotime($row['updated']);
1159  $ok = true;
1160  }
1161  }
1162 
1163  return $ok;
1164  }
1165 
1173  public function saveUserResult($userresult)
1174  {
1175  $time = time();
1176  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
1177  if (is_null($userresult->created)) {
1178  $sql = "INSERT INTO {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' (resource_link_pk, ' .
1179  'lti_user_id, lti_result_sourcedid, created, updated) ' .
1180  'VALUES (:rlid, :u_id, :sourcedid, :created, :updated)';
1181  $query = $this->db->prepare($sql);
1182  $query->bindValue('rlid', $userresult->getResourceLink()->getRecordId(), \PDO::PARAM_INT);
1183  $query->bindValue('u_id', $userresult->getId(LTI\ToolProvider::ID_SCOPE_ID_ONLY), \PDO::PARAM_STR);
1184  $query->bindValue('sourcedid', $userresult->ltiResultSourcedId, \PDO::PARAM_STR);
1185  $query->bindValue('created', $now, \PDO::PARAM_STR);
1186  $query->bindValue('updated', $now, \PDO::PARAM_STR);
1187  } else {
1188  $sql = "UPDATE {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1189  'SET lti_result_sourcedid = :sourcedid, updated = :updated ' .
1190  'WHERE (user_result_pk = :id)';
1191  $query = $this->db->prepare($sql);
1192  $query->bindValue('sourcedid', $userresult->ltiResultSourcedId, \PDO::PARAM_STR);
1193  $query->bindValue('updated', $now, \PDO::PARAM_STR);
1194  $query->bindValue('id', $userresult->getRecordId(), \PDO::PARAM_INT);
1195  }
1196  $ok = $query->execute();
1197  if ($ok) {
1198  if (is_null($userresult->created)) {
1199  $userresult->setRecordId($this->getLastInsertId(static::USER_RESULT_TABLE_NAME));
1200  $userresult->created = $time;
1201  }
1202  $userresult->updated = $time;
1203  }
1204 
1205  return $ok;
1206  }
1207 
1215  public function deleteUserResult($userresult)
1216  {
1217  $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1218  'WHERE (user_result_pk = :id)';
1219  $query = $this->db->prepare($sql);
1220  $query->bindValue('id', $userresult->getRecordId(), \PDO::PARAM_INT);
1221  $ok = $query->execute();
1222 
1223  if ($ok) {
1224  $userresult->initialize();
1225  }
1226 
1227  return $ok;
1228  }
1229 
1230  protected function getLastInsertId($tableName)
1231  {
1232  return intval($this->db->lastInsertId());
1233  }
1234 
1235 }
$dbTableNamePrefix
Prefix for database table names.
Class to provide a connection to a persistent store for LTI objects.
loadUserResult($userresult)
Load user object.
getUserResultSourcedIDsResourceLink($resourceLink, $localOnly, $idScope)
Get array of user objects.
loadResourceLink($resourceLink)
Load resource link object.
const ID_SCOPE_ID_ONLY
Use ID value only.
Class to represent a tool consumer.
static getConsumerKey($key)
Return a hash of a consumer key for values longer than 255 characters.
Class to represent a tool consumer context.
Definition: Context.php:17
Class to represent an LTI Data Connector for PDO connections.
saveToolConsumer($consumer)
Save tool consumer object.
Class to represent a tool consumer nonce.
Class to represent a tool consumer resource link share.
static fromRecordId($id, $dataConnector)
Load the user from the database.
Definition: UserResult.php:238
saveContext($context)
Save context object.
loadToolConsumer($consumer)
Load tool consumer object.
getSharesResourceLink($resourceLink)
Get array of shares defined for this resource link.
deleteResourceLink($resourceLink)
Delete resource link object.
loadContext($context)
Load context object.
Class to represent a tool consumer user.
Definition: UserResult.php:15
saveResourceLinkShareKey($shareKey)
Save resource link share key object.
__construct($db, $dbTableNamePrefix='')
Class constructor.
deleteToolConsumer0($consumer)
Delete tool consumer object.
getToolConsumers()
Load tool consumer objects.
Class to represent a tool consumer resource link share key.
saveResourceLink($resourceLink)
Save resource link object.
loadResourceLinkShareKey($shareKey)
Load resource link share key object.
deleteResourceLinkShareKey($shareKey)
Delete resource link share key object.
saveUserResult($userresult)
Save user object.
deleteUserResult($userresult)
Delete user object.