LTI Integration Library 4.10.3
PHP class library for building LTI integrations
 
Loading...
Searching...
No Matches
DataConnector_pg.php
1<?php
2
4
5use ceLTIc\LTI;
16
24###
25# NB This class assumes that a PostgreSQL connection has already been opened to the appropriate schema
26###
27
28
30{
31###
32### Platform methods
33###
34
42 public function loadPlatform($platform)
43 {
44 $ok = false;
45 $allowMultiple = false;
46 if (!is_null($platform->getRecordId())) {
47 $sql = sprintf('SELECT consumer_pk, name, consumer_key, secret, ' .
48 'platform_id, client_id, deployment_id, public_key, ' .
49 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
50 'profile, tool_proxy, settings, protected, enabled, ' .
51 'enable_from, enable_until, last_access, created, updated ' .
52 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
53 'WHERE consumer_pk = %d', $platform->getRecordId());
54 } elseif (!empty($platform->platformId)) {
55 if (empty($platform->clientId)) {
56 $allowMultiple = true;
57 $sql = sprintf('SELECT consumer_pk, name, consumer_key, secret, ' .
58 'platform_id, client_id, deployment_id, public_key, ' .
59 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
60 'profile, tool_proxy, settings, protected, enabled, ' .
61 'enable_from, enable_until, last_access, created, updated ' .
62 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
63 'WHERE (platform_id = %s) ', $this->escape($platform->platformId));
64 } elseif (empty($platform->deploymentId)) {
65 $allowMultiple = true;
66 $sql = sprintf('SELECT consumer_pk, name, consumer_key, secret, ' .
67 'platform_id, client_id, deployment_id, public_key, ' .
68 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
69 'profile, tool_proxy, settings, protected, enabled, ' .
70 'enable_from, enable_until, last_access, created, updated ' .
71 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
72 'WHERE (platform_id = %s) AND (client_id = %s)', $this->escape($platform->platformId),
73 $this->escape($platform->clientId));
74 } else {
75 $sql = sprintf('SELECT consumer_pk, name, consumer_key, secret, ' .
76 'platform_id, client_id, deployment_id, public_key, ' .
77 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
78 'profile, tool_proxy, settings, protected, enabled, ' .
79 'enable_from, enable_until, last_access, created, updated ' .
80 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
81 'WHERE (platform_id = %s) AND (client_id = %s) AND (deployment_id = %s)', $this->escape($platform->platformId),
82 $this->escape($platform->clientId), $this->escape($platform->deploymentId));
83 }
84 } else {
85 $sql = sprintf('SELECT consumer_pk, name, consumer_key, secret, ' .
86 'platform_id, client_id, deployment_id, public_key, ' .
87 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
88 'profile, tool_proxy, settings, protected, enabled, ' .
89 'enable_from, enable_until, last_access, created, updated ' .
90 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
91 "WHERE consumer_key = %s", $this->escape($platform->getKey()));
92 }
93 $rsConsumer = $this->executeQuery($sql);
94 if ($rsConsumer) {
95 $row = pg_fetch_object($rsConsumer);
96 if ($row && ($allowMultiple || !pg_fetch_object($rsConsumer))) {
97 $platform->setRecordId(intval($row->consumer_pk));
98 $platform->name = $row->name;
99 $platform->setkey($row->consumer_key);
100 $platform->secret = $row->secret;
101 $platform->platformId = $row->platform_id;
102 $platform->clientId = $row->client_id;
103 $platform->deploymentId = $row->deployment_id;
104 $platform->rsaKey = $row->public_key;
105 $platform->ltiVersion = $row->lti_version;
106 $platform->signatureMethod = $row->signature_method;
107 $platform->consumerName = $row->consumer_name;
108 $platform->consumerVersion = $row->consumer_version;
109 $platform->consumerGuid = $row->consumer_guid;
110 $platform->profile = Util::jsonDecode($row->profile);
111 $platform->toolProxy = $row->tool_proxy;
112 $settings = Util::jsonDecode($row->settings, true);
113 if (!is_array($settings)) {
114 $settings = @unserialize($row->settings); // check for old serialized setting
115 }
116 if (!is_array($settings)) {
117 $settings = array();
118 }
119 $platform->setSettings($settings);
120 $platform->protected = ($row->protected === 't');
121 $platform->enabled = ($row->enabled === 't');
122 $platform->enableFrom = null;
123 if (!is_null($row->enable_from)) {
124 $platform->enableFrom = strtotime($row->enable_from);
125 }
126 $platform->enableUntil = null;
127 if (!is_null($row->enable_until)) {
128 $platform->enableUntil = strtotime($row->enable_until);
129 }
130 $platform->lastAccess = null;
131 if (!is_null($row->last_access)) {
132 $platform->lastAccess = strtotime($row->last_access);
133 }
134 $platform->created = strtotime($row->created);
135 $platform->updated = strtotime($row->updated);
136 $this->fixPlatformSettings($platform, false);
137 $ok = true;
138 }
139 }
140
141 return $ok;
142 }
143
151 public function savePlatform($platform)
152 {
153 $id = $platform->getRecordId();
154 $protected = ($platform->protected) ? 'true' : 'false';
155 $enabled = ($platform->enabled) ? 'true' : 'false';
156 $profile = (!empty($platform->profile)) ? json_encode($platform->profile) : null;
157 $this->fixPlatformSettings($platform, true);
158 $settingsValue = json_encode($platform->getSettings());
159 $this->fixPlatformSettings($platform, false);
160 $time = time();
161 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
162 $from = null;
163 if (!is_null($platform->enableFrom)) {
164 $from = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableFrom);
165 }
166 $until = null;
167 if (!is_null($platform->enableUntil)) {
168 $until = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableUntil);
169 }
170 $last = null;
171 if (!is_null($platform->lastAccess)) {
172 $last = date($this->dateFormat, $platform->lastAccess);
173 }
174 if (empty($id)) {
175 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' (consumer_key, name, secret, ' .
176 'platform_id, client_id, deployment_id, public_key, ' .
177 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
178 'profile, tool_proxy, settings, protected, enabled, ' .
179 'enable_from, enable_until, last_access, created, updated) ' .
180 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
181 $this->escape($platform->getKey()), $this->escape($platform->name), $this->escape($platform->secret),
182 $this->escape($platform->platformId), $this->escape($platform->clientId), $this->escape($platform->deploymentId),
183 $this->escape($platform->rsaKey), $this->escape($platform->ltiVersion), $this->escape($platform->signatureMethod),
184 $this->escape($platform->consumerName), $this->escape($platform->consumerVersion),
185 $this->escape($platform->consumerGuid), $this->escape($profile), $this->escape($platform->toolProxy),
186 $this->escape($settingsValue), $protected, $enabled, $this->escape($from), $this->escape($until),
187 $this->escape($last), $this->escape($now), $this->escape($now));
188 } else {
189 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' SET ' .
190 'consumer_key = %s, name = %s, secret = %s, ' .
191 'platform_id = %s, client_id = %s, deployment_id = %s, public_key = %s, ' .
192 'lti_version = %s, signature_method = %s, ' .
193 'consumer_name = %s, consumer_version = %s, consumer_guid = %s, ' .
194 'profile = %s, tool_proxy = %s, settings = %s, ' .
195 'protected = %s, enabled = %s, enable_from = %s, enable_until = %s, last_access = %s, updated = %s ' .
196 'WHERE consumer_pk = %d', $this->escape($platform->getKey()), $this->escape($platform->name),
197 $this->escape($platform->secret), $this->escape($platform->platformId), $this->escape($platform->clientId),
198 $this->escape($platform->deploymentId), $this->escape($platform->rsaKey), $this->escape($platform->ltiVersion),
199 $this->escape($platform->signatureMethod), $this->escape($platform->consumerName),
200 $this->escape($platform->consumerVersion), $this->escape($platform->consumerGuid), $this->escape($profile),
201 $this->escape($platform->toolProxy), $this->escape($settingsValue), $protected, $enabled, $this->escape($from),
202 $this->escape($until), $this->escape($last), $this->escape($now), $platform->getRecordId());
203 }
204 $ok = $this->executeQuery($sql);
205 if ($ok) {
206 if (empty($id)) {
207 $platform->setRecordId($this->insert_id());
208 $platform->created = $time;
209 }
210 $platform->updated = $time;
211 }
212
213 return $ok;
214 }
215
223 public function deletePlatform($platform)
224 {
225// Delete any access token value for this consumer
226 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::ACCESS_TOKEN_TABLE_NAME . ' WHERE consumer_pk = %d',
227 $platform->getRecordId());
228 $this->executeQuery($sql);
229
230// Delete any nonce values for this consumer
231 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE consumer_pk = %d',
232 $platform->getRecordId());
233 $this->executeQuery($sql);
234
235// Delete any outstanding share keys for resource links for this consumer
236 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
237 "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
238 'WHERE consumer_pk = %d)', $platform->getRecordId());
239 $this->executeQuery($sql);
240
241// Delete any outstanding share keys for resource links for contexts in this consumer
242 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
243 "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
244 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk WHERE c.consumer_pk = %d)',
245 $platform->getRecordId());
246 $this->executeQuery($sql);
247
248// Delete any users in resource links for this consumer
249 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
250 "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
251 'WHERE consumer_pk = %d)', $platform->getRecordId());
252 $this->executeQuery($sql);
253
254// Delete any users in resource links for contexts in this consumer
255 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
256 "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
257 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk WHERE c.consumer_pk = %d)',
258 $platform->getRecordId());
259 $this->executeQuery($sql);
260
261// Update any resource links for which this consumer is acting as a primary resource link
262 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
263 'SET primary_resource_link_pk = NULL, share_approved = NULL ' .
264 'WHERE primary_resource_link_pk IN ' .
265 "(SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
266 'WHERE consumer_pk = %d)', $platform->getRecordId());
267 $ok = $this->executeQuery($sql);
268
269// Update any resource links for contexts in which this consumer is acting as a primary resource link
270 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
271 'SET primary_resource_link_pk = NULL, share_approved = NULL ' .
272 'WHERE primary_resource_link_pk IN ' .
273 "(SELECT rl.resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
274 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
275 'WHERE c.consumer_pk = %d)', $platform->getRecordId());
276 $ok = $this->executeQuery($sql);
277
278// Delete any resource links for this consumer
279 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
280 'WHERE consumer_pk = %d', $platform->getRecordId());
281 $this->executeQuery($sql);
282
283// Delete any resource links for contexts in this consumer
284 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
285 'WHERE context_pk IN (' .
286 "SELECT context_pk FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' . 'WHERE consumer_pk = %d)',
287 $platform->getRecordId());
288 $this->executeQuery($sql);
289
290// Delete any contexts for this consumer
291 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
292 'WHERE consumer_pk = %d', $platform->getRecordId());
293 $this->executeQuery($sql);
294
295// Delete consumer
296 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
297 'WHERE consumer_pk = %d', $platform->getRecordId());
298 $ok = $this->executeQuery($sql);
299
300 if ($ok) {
301 $platform->initialize();
302 }
303
304 return $ok;
305 }
306
312 public function getPlatforms()
313 {
314 $platforms = array();
315
316 $sql = 'SELECT consumer_pk, consumer_key, name, secret, ' .
317 'platform_id, client_id, deployment_id, public_key, ' .
318 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
319 'profile, tool_proxy, settings, protected, enabled, ' .
320 'enable_from, enable_until, last_access, created, updated ' .
321 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
322 'ORDER BY name';
323 $rsConsumers = $this->executeQuery($sql);
324 if ($rsConsumers) {
325 while ($row = pg_fetch_object($rsConsumers)) {
326 $platform = new Platform($this);
327 $platform->setRecordId(intval($row->consumer_pk));
328 $platform->name = $row->name;
329 $platform->setKey($row->consumer_key);
330 $platform->secret = $row->secret;
331 $platform->platformId = $row->platform_id;
332 $platform->clientId = $row->client_id;
333 $platform->deploymentId = $row->deployment_id;
334 $platform->rsaKey = $row->public_key;
335 $platform->ltiVersion = $row->lti_version;
336 $platform->signatureMethod = $row->signature_method;
337 $platform->consumerName = $row->consumer_name;
338 $platform->consumerVersion = $row->consumer_version;
339 $platform->consumerGuid = $row->consumer_guid;
340 $platform->profile = Util::jsonDecode($row->profile);
341 $platform->toolProxy = $row->tool_proxy;
342 $settings = Util::jsonDecode($row->settings, true);
343 if (!is_array($settings)) {
344 $settings = @unserialize($row->settings); // check for old serialized setting
345 }
346 if (!is_array($settings)) {
347 $settings = array();
348 }
349 $platform->setSettings($settings);
350 $platform->protected = ($row->protected === 't');
351 $platform->enabled = ($row->enabled === 't');
352 $platform->enableFrom = null;
353 if (!is_null($row->enable_from)) {
354 $platform->enableFrom = strtotime($row->enable_from);
355 }
356 $platform->enableUntil = null;
357 if (!is_null($row->enable_until)) {
358 $platform->enableUntil = strtotime($row->enable_until);
359 }
360 $platform->lastAccess = null;
361 if (!is_null($row->last_access)) {
362 $platform->lastAccess = strtotime($row->last_access);
363 }
364 $platform->created = strtotime($row->created);
365 $platform->updated = strtotime($row->updated);
366 $this->fixPlatformSettings($platform, false);
367 $platforms[] = $platform;
368 }
369 pg_free_result($rsConsumers);
370 }
371
372 return $platforms;
373 }
374
375###
376### Context methods
377###
378
386 public function loadContext($context)
387 {
388 $ok = false;
389 if (!is_null($context->getRecordId())) {
390 $sql = sprintf('SELECT context_pk, consumer_pk, title, lti_context_id, type, settings, created, updated ' .
391 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
392 'WHERE (context_pk = %d)', $context->getRecordId());
393 } else {
394 $sql = sprintf('SELECT context_pk, consumer_pk, title, lti_context_id, type, settings, created, updated ' .
395 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
396 'WHERE (consumer_pk = %d) AND (lti_context_id = %s)', $context->getPlatform()->getRecordId(),
397 $this->escape($context->ltiContextId));
398 }
399 $rsContext = $this->executeQuery($sql);
400 if ($rsContext) {
401 $row = pg_fetch_object($rsContext);
402 if ($row) {
403 $context->setRecordId(intval($row->context_pk));
404 $context->setPlatformId(intval($row->consumer_pk));
405 $context->title = $row->title;
406 $context->ltiContextId = $row->lti_context_id;
407 $context->type = $row->type;
408 $settings = Util::jsonDecode($row->settings, true);
409 if (!is_array($settings)) {
410 $settings = @unserialize($row->settings); // check for old serialized setting
411 }
412 if (!is_array($settings)) {
413 $settings = array();
414 }
415 $context->setSettings($settings);
416 $context->created = strtotime($row->created);
417 $context->updated = strtotime($row->updated);
418 $ok = true;
419 }
420 }
421
422 return $ok;
423 }
424
432 public function saveContext($context)
433 {
434 $time = time();
435 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
436 $settingsValue = json_encode($context->getSettings());
437 $id = $context->getRecordId();
438 $consumer_pk = $context->getPlatform()->getRecordId();
439 if (empty($id)) {
440 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' (consumer_pk, title, ' .
441 'lti_context_id, type, settings, created, updated) ' .
442 'VALUES (%d, %s, %s, %s, %s, %s, %s)', $consumer_pk, $this->escape($context->title),
443 $this->escape($context->ltiContextId), $this->escape($context->type), $this->escape($settingsValue),
444 $this->escape($now), $this->escape($now));
445 } else {
446 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' SET ' .
447 'title = %s, lti_context_id = %s, type = %s, settings = %s, ' .
448 'updated = %s' .
449 'WHERE (consumer_pk = %d) AND (context_pk = %d)', $this->escape($context->title),
450 $this->escape($context->ltiContextId), $this->escape($context->type), $this->escape($settingsValue),
451 $this->escape($now), $consumer_pk, $id);
452 }
453 $ok = $this->executeQuery($sql);
454 if ($ok) {
455 if (empty($id)) {
456 $context->setRecordId($this->insert_id());
457 $context->created = $time;
458 }
459 $context->updated = $time;
460 }
461
462 return $ok;
463 }
464
472 public function deleteContext($context)
473 {
474// Delete any outstanding share keys for resource links for this context
475 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
476 "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
477 'WHERE context_pk = %d)', $context->getRecordId());
478 $this->executeQuery($sql);
479
480// Delete any users in resource links for this context
481 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
482 "WHERE resource_link_pk IN (SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
483 'WHERE context_pk = %d)', $context->getRecordId());
484 $this->executeQuery($sql);
485
486// Update any resource links for which this consumer is acting as a primary resource link
487 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
488 'SET primary_resource_link_pk = null, share_approved = null ' .
489 'WHERE primary_resource_link_pk IN ' .
490 "(SELECT resource_link_pk FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' WHERE context_pk = %d)',
491 $context->getRecordId());
492 $ok = $this->executeQuery($sql);
493
494// Delete any resource links for this consumer
495 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
496 'WHERE context_pk = %d', $context->getRecordId());
497 $this->executeQuery($sql);
498
499// Delete context
500 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ', 'WHERE context_pk = %d',
501 $context->getRecordId());
502 $ok = $this->executeQuery($sql);
503 if ($ok) {
504 $context->initialize();
505 }
506
507 return $ok;
508 }
509
510###
511### ResourceLink methods
512###
513
521 public function loadResourceLink($resourceLink)
522 {
523 $ok = false;
524 if (!is_null($resourceLink->getRecordId())) {
525 $sql = sprintf('SELECT resource_link_pk, context_pk, consumer_pk, title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' .
526 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
527 'WHERE (resource_link_pk = %d)', $resourceLink->getRecordId());
528 } elseif (!is_null($resourceLink->getContext())) {
529 $sql = sprintf('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 ' .
530 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r ' .
531 'WHERE (r.lti_resource_link_id = %s) AND ((r.context_pk = %d) OR (r.consumer_pk IN (' .
532 'SELECT c.consumer_pk ' .
533 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ' .
534 'WHERE (c.context_pk = %d))))', $this->escape($resourceLink->getId()), $resourceLink->getContext()->getRecordId(),
535 $resourceLink->getContext()->getRecordId());
536 } else {
537 $sql = sprintf('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 ' .
538 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r LEFT OUTER JOIN ' .
539 $this->dbTableNamePrefix . static::CONTEXT_TABLE_NAME . ' c ON r.context_pk = c.context_pk ' .
540 ' WHERE ((r.consumer_pk = %d) OR (c.consumer_pk = %d)) AND (lti_resource_link_id = %s)',
541 $resourceLink->getPlatform()->getRecordId(), $resourceLink->getPlatform()->getRecordId(),
542 $this->escape($resourceLink->getId()));
543 }
544 $rsResourceLink = $this->executeQuery($sql);
545 if ($rsResourceLink) {
546 $row = pg_fetch_object($rsResourceLink);
547 if ($row) {
548 $resourceLink->setRecordId(intval($row->resource_link_pk));
549 if (!is_null($row->context_pk)) {
550 $resourceLink->setContextId(intval($row->context_pk));
551 } else {
552 $resourceLink->setContextId(null);
553 }
554 if (!is_null($row->consumer_pk)) {
555 $resourceLink->setPlatformId(intval($row->consumer_pk));
556 } else {
557 $resourceLink->setPlatformId(null);
558 }
559 $resourceLink->title = $row->title;
560 $resourceLink->ltiResourceLinkId = $row->lti_resource_link_id;
561 $settings = Util::jsonDecode($row->settings, true);
562 if (!is_array($settings)) {
563 $settings = @unserialize($row->settings); // check for old serialized setting
564 }
565 if (!is_array($settings)) {
566 $settings = array();
567 }
568 $resourceLink->setSettings($settings);
569 if (!is_null($row->primary_resource_link_pk)) {
570 $resourceLink->primaryResourceLinkId = intval($row->primary_resource_link_pk);
571 } else {
572 $resourceLink->primaryResourceLinkId = null;
573 }
574 $resourceLink->shareApproved = (is_null($row->share_approved)) ? null : (intval($row->share_approved) === 1);
575 $resourceLink->created = strtotime($row->created);
576 $resourceLink->updated = strtotime($row->updated);
577 $ok = true;
578 }
579 }
580
581 return $ok;
582 }
583
591 public function saveResourceLink($resourceLink)
592 {
593 if (is_null($resourceLink->shareApproved)) {
594 $approved = 'NULL';
595 } elseif ($resourceLink->shareApproved) {
596 $approved = 'true';
597 } else {
598 $approved = 'false';
599 }
600 if (empty($resourceLink->primaryResourceLinkId)) {
601 $primaryResourceLinkId = 'NULL';
602 } else {
603 $primaryResourceLinkId = strval($resourceLink->primaryResourceLinkId);
604 }
605 $time = time();
606 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
607 $settingsValue = json_encode($resourceLink->getSettings());
608 if (!is_null($resourceLink->getContext())) {
609 $consumerId = 'NULL';
610 $contextId = strval($resourceLink->getContext()->getRecordId());
611 } elseif (!is_null($resourceLink->getContextId())) {
612 $consumerId = 'NULL';
613 $contextId = strval($resourceLink->getContextId());
614 } else {
615 $consumerId = strval($resourceLink->getPlatform()->getRecordId());
616 $contextId = 'NULL';
617 }
618 $id = $resourceLink->getRecordId();
619 if (empty($id)) {
620 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' (consumer_pk, context_pk, ' .
621 'title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated) ' .
622 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)', $consumerId, $contextId, $this->escape($resourceLink->title),
623 $this->escape($resourceLink->getId()), $this->escape($settingsValue), $primaryResourceLinkId, $approved,
624 $this->escape($now), $this->escape($now));
625 } elseif ($contextId !== 'NULL') {
626 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' SET ' .
627 'consumer_pk = %s, title = %s, lti_resource_link_id = %s, settings = %s, ' .
628 'primary_resource_link_pk = %s, share_approved = %s, updated = %s ' .
629 'WHERE (context_pk = %s) AND (resource_link_pk = %d)', $consumerId, $this->escape($resourceLink->title),
630 $this->escape($resourceLink->getId()), $this->escape($settingsValue), $primaryResourceLinkId, $approved,
631 $this->escape($now), $contextId, $id);
632 } else {
633 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' SET ' .
634 'context_pk = NULL, title = %s, lti_resource_link_id = %s, settings = %s, ' .
635 'primary_resource_link_pk = %s, share_approved = %s, updated = %s ' .
636 'WHERE (consumer_pk = %s) AND (resource_link_pk = %d)', $this->escape($resourceLink->title),
637 $this->escape($resourceLink->getId()), $this->escape($settingsValue), $primaryResourceLinkId, $approved,
638 $this->escape($now), $consumerId, $id);
639 }
640 $ok = $this->executeQuery($sql);
641 if ($ok) {
642 if (empty($id)) {
643 $resourceLink->setRecordId($this->insert_id());
644 $resourceLink->created = $time;
645 }
646 $resourceLink->updated = $time;
647 }
648
649 return $ok;
650 }
651
659 public function deleteResourceLink($resourceLink)
660 {
661// Delete any outstanding share keys for resource links for this consumer
662 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
663 'WHERE (resource_link_pk = %d)', $resourceLink->getRecordId());
664 $ok = $this->executeQuery($sql);
665
666// Delete users
667 if ($ok) {
668 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
669 'WHERE (resource_link_pk = %d)', $resourceLink->getRecordId());
670 $ok = $this->executeQuery($sql);
671 }
672
673// Update any resource links for which this is the primary resource link
674 if ($ok) {
675 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
676 'SET primary_resource_link_pk = NULL ' .
677 'WHERE (primary_resource_link_pk = %d)', $resourceLink->getRecordId());
678 $ok = $this->executeQuery($sql);
679 }
680
681// Delete resource link
682 if ($ok) {
683 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
684 'WHERE (resource_link_pk = %s)', $resourceLink->getRecordId());
685 $ok = $this->executeQuery($sql);
686 }
687
688 if ($ok) {
689 $resourceLink->initialize();
690 }
691
692 return $ok;
693 }
694
707 public function getUserResultSourcedIDsResourceLink($resourceLink, $localOnly, $idScope)
708 {
709 $userResults = array();
710
711 if ($localOnly) {
712 $sql = sprintf('SELECT u.user_result_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
713 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' AS u ' .
714 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .
715 'ON u.resource_link_pk = rl.resource_link_pk ' .
716 "WHERE (rl.resource_link_pk = %d) AND (rl.primary_resource_link_pk IS NULL)", $resourceLink->getRecordId());
717 } else {
718 $sql = sprintf('SELECT u.user_result_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
719 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' AS u ' .
720 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .
721 'ON u.resource_link_pk = rl.resource_link_pk ' .
722 'WHERE ((rl.resource_link_pk = %d) AND (rl.primary_resource_link_pk IS NULL)) OR ' .
723 '((rl.primary_resource_link_pk = %d) AND share_approved)', $resourceLink->getRecordId(),
724 $resourceLink->getRecordId());
725 }
726 $rsUser = $this->executeQuery($sql);
727 if ($rsUser) {
728 while ($row = pg_fetch_object($rsUser)) {
729 $userresult = LTI\UserResult::fromResourceLink($resourceLink, $row->lti_user_id);
730 if (is_null($idScope)) {
731 $userResults[] = $userresult;
732 } else {
733 $userResults[$userresult->getId($idScope)] = $userresult;
734 }
735 }
736 }
737
738 return $userResults;
739 }
740
748 public function getSharesResourceLink($resourceLink)
749 {
750 $shares = array();
751
752 $sql = sprintf('SELECT c.consumer_name, r.resource_link_pk, r.title, r.share_approved ' .
753 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS r ' .
754 "INNER JOIN {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' AS c ON r.consumer_pk = c.consumer_pk ' .
755 'WHERE (r.primary_resource_link_pk = %d) ' .
756 'UNION ' .
757 'SELECT c2.consumer_name, r2.resource_link_pk, r2.title, r2.share_approved ' .
758 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS r2 ' .
759 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' AS x ON r2.context_pk = x.context_pk ' .
760 "INNER JOIN {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' AS c2 ON x.consumer_pk = c2.consumer_pk ' .
761 'WHERE (r2.primary_resource_link_pk = %d) ' .
762 'ORDER BY consumer_name, title', $resourceLink->getRecordId(), $resourceLink->getRecordId());
763 $rsShare = $this->executeQuery($sql);
764 if ($rsShare) {
765 while ($row = pg_fetch_object($rsShare)) {
766 $share = new LTI\ResourceLinkShare();
767 $share->consumerName = $row->consumer_name;
768 $share->resourceLinkId = intval($row->resource_link_pk);
769 $share->title = $row->title;
770 $share->approved = (intval($row->share_approved) === 1);
771 $shares[] = $share;
772 }
773 }
774
775 return $shares;
776 }
777
778###
779### PlatformNonce methods
780###
781
789 public function loadPlatformNonce($nonce)
790 {
791 if (parent::useMemcache()) {
792 $ok = parent::loadPlatformNonce($nonce);
793 } else {
794 $ok = false;
795
796// Delete any expired nonce values
797 $now = date("{$this->dateFormat} {$this->timeFormat}", time());
798 $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . " WHERE expires <= '{$now}'";
799 $this->executeQuery($sql);
800
801// Load the nonce
802 $sql = sprintf("SELECT value AS T FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE (consumer_pk = %d) AND (value = %s)',
803 $nonce->getPlatform()->getRecordId(), $this->escape($nonce->getValue()));
804 $rsNonce = $this->executeQuery($sql, false);
805 if ($rsNonce) {
806 if (pg_fetch_object($rsNonce)) {
807 $ok = true;
808 }
809 }
810 }
811
812 return $ok;
813 }
814
822 public function savePlatformNonce($nonce)
823 {
824 if (parent::useMemcache()) {
825 $ok = parent::savePlatformNonce($nonce);
826 } else {
827 $expires = date("{$this->dateFormat} {$this->timeFormat}", $nonce->expires);
828 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . " (consumer_pk, value, expires) VALUES (%d, %s, %s)",
829 $nonce->getPlatform()->getRecordId(), $this->escape($nonce->getValue()), $this->escape($expires));
830 $ok = $this->executeQuery($sql);
831 }
832
833 return $ok;
834 }
835
843 public function deletePlatformNonce($nonce)
844 {
845 if (parent::useMemcache()) {
846 $ok = parent::deletePlatformNonce($nonce);
847 } else {
848 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' WHERE (consumer_pk = %d) AND (value = %s)',
849 $nonce->getPlatform()->getRecordId(), $this->escape($nonce->getValue()));
850 $ok = $this->executeQuery($sql);
851 }
852
853 return $ok;
854 }
855
856###
857### AccessToken methods
858###
859
867 public function loadAccessToken($accessToken)
868 {
869 if (parent::useMemcache()) {
870 $ok = parent::loadAccessToken($accessToken);
871 } else {
872 $ok = false;
873 $consumer_pk = $accessToken->getPlatform()->getRecordId();
874 $sql = sprintf('SELECT scopes, token, expires, created, updated ' .
875 "FROM {$this->dbTableNamePrefix}" . static::ACCESS_TOKEN_TABLE_NAME . ' ' .
876 'WHERE (consumer_pk = %d)', $consumer_pk);
877 $rsAccessToken = $this->executeQuery($sql, false);
878 if ($rsAccessToken) {
879 $row = pg_fetch_object($rsAccessToken);
880 if ($row) {
881 $scopes = Util::jsonDecode($row->scopes, true);
882 if (!is_array($scopes)) {
883 $scopes = array();
884 }
885 $accessToken->scopes = $scopes;
886 $accessToken->token = $row->token;
887 $accessToken->expires = strtotime($row->expires);
888 $accessToken->created = strtotime($row->created);
889 $accessToken->updated = strtotime($row->updated);
890 $ok = true;
891 }
892 }
893 }
894
895 return $ok;
896 }
897
905 public function saveAccessToken($accessToken)
906 {
907 if (parent::useMemcache()) {
908 $ok = parent::saveAccessToken($accessToken);
909 } else {
910 $consumer_pk = $accessToken->getPlatform()->getRecordId();
911 $scopes = json_encode($accessToken->scopes, JSON_UNESCAPED_SLASHES);
912 $token = $accessToken->token;
913 $expires = date("{$this->dateFormat} {$this->timeFormat}", $accessToken->expires);
914 $time = time();
915 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
916 if (empty($accessToken->created)) {
917 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::ACCESS_TOKEN_TABLE_NAME . ' ' .
918 '(consumer_pk, scopes, token, expires, created, updated) ' .
919 'VALUES (%d, %s, %s, %s, %s, %s)', $consumer_pk, $this->escape($scopes), $this->escape($token),
920 $this->escape($expires), $this->escape($now), $this->escape($now));
921 } else {
922 $sql = sprintf('UPDATE ' . $this->dbTableNamePrefix . static::ACCESS_TOKEN_TABLE_NAME . ' ' .
923 'SET scopes = %s, token = %s, expires = %s, updated = %s WHERE consumer_pk = %d', $this->escape($scopes),
924 $this->escape($token), $this->escape($expires), $this->escape($now), $consumer_pk);
925 }
926 $ok = $this->executeQuery($sql);
927 }
928
929 return $ok;
930 }
931
932###
933### ResourceLinkShareKey methods
934###
935
943 public function loadResourceLinkShareKey($shareKey)
944 {
945 $ok = false;
946
947// Clear expired share keys
948 $now = date("{$this->dateFormat} {$this->timeFormat}", time());
949 $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . " WHERE expires <= '{$now}'";
950 $this->executeQuery($sql);
951
952// Load share key
953 $id = pg_escape_string($this->db, $shareKey->getId());
954 $sql = 'SELECT resource_link_pk, auto_approve, expires ' .
955 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
956 "WHERE share_key_id = '{$id}'";
957 $rsShareKey = $this->executeQuery($sql);
958 if ($rsShareKey) {
959 $row = pg_fetch_object($rsShareKey);
960 if ($row) {
961 $shareKey->resourceLinkId = intval($row->resource_link_pk);
962 $shareKey->autoApprove = (intval($row->auto_approve) === 1);
963 $shareKey->expires = strtotime($row->expires);
964 $ok = true;
965 }
966 }
967
968 return $ok;
969 }
970
978 public function saveResourceLinkShareKey($shareKey)
979 {
980 if ($shareKey->autoApprove) {
981 $approve = 'true';
982 } else {
983 $approve = 'false';
984 }
985 $expires = date("{$this->dateFormat} {$this->timeFormat}", $shareKey->expires);
986 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
987 '(share_key_id, resource_link_pk, auto_approve, expires) ' .
988 "VALUES (%s, %d, {$approve}, '{$expires}')", $this->escape($shareKey->getId()), $shareKey->resourceLinkId);
989 $ok = $this->executeQuery($sql);
990
991 return $ok;
992 }
993
1001 public function deleteResourceLinkShareKey($shareKey)
1002 {
1003 $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . " WHERE share_key_id = '{$shareKey->getId()}'";
1004
1005 $ok = $this->executeQuery($sql);
1006
1007 if ($ok) {
1008 $shareKey->initialize();
1009 }
1010
1011 return $ok;
1012 }
1013
1014###
1015### UserResult methods
1016###
1017
1025 public function loadUserResult($userresult)
1026 {
1027 $ok = false;
1028 if (!is_null($userresult->getRecordId())) {
1029 $sql = sprintf('SELECT user_result_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1030 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1031 'WHERE (user_result_pk = %d)', $userresult->getRecordId());
1032 } else {
1033 $sql = sprintf('SELECT user_result_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1034 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1035 'WHERE (resource_link_pk = %d) AND (lti_user_id = %s)', $userresult->getResourceLink()->getRecordId(),
1036 $this->escape($userresult->getId(LTI\Tool::ID_SCOPE_ID_ONLY)));
1037 }
1038 $rsUserResult = $this->executeQuery($sql);
1039 if ($rsUserResult) {
1040 $row = pg_fetch_object($rsUserResult);
1041 if ($row) {
1042 $userresult->setRecordId(intval($row->user_result_pk));
1043 $userresult->setResourceLinkId(intval($row->resource_link_pk));
1044 $userresult->ltiUserId = $row->lti_user_id;
1045 $userresult->ltiResultSourcedId = $row->lti_result_sourcedid;
1046 $userresult->created = strtotime($row->created);
1047 $userresult->updated = strtotime($row->updated);
1048 $ok = true;
1049 }
1050 }
1051
1052 return $ok;
1053 }
1054
1062 public function saveUserResult($userresult)
1063 {
1064 $time = time();
1065 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
1066 if (is_null($userresult->created)) {
1067 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' (resource_link_pk, ' .
1068 'lti_user_id, lti_result_sourcedid, created, updated) ' .
1069 'VALUES (%d, %s, %s, %s, %s)', $userresult->getResourceLink()->getRecordId(),
1070 $this->escape($userresult->getId(LTI\Tool::ID_SCOPE_ID_ONLY)), $this->escape($userresult->ltiResultSourcedId),
1071 $this->escape($now), $this->escape($now));
1072 } else {
1073 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1074 'SET lti_result_sourcedid = %s, updated = %s ' .
1075 'WHERE (user_result_pk = %d)', $this->escape($userresult->ltiResultSourcedId), $this->escape($now),
1076 $userresult->getRecordId());
1077 }
1078 $ok = $this->executeQuery($sql);
1079 if ($ok) {
1080 if (is_null($userresult->created)) {
1081 $userresult->setRecordId($this->insert_id());
1082 $userresult->created = $time;
1083 }
1084 $userresult->updated = $time;
1085 }
1086
1087 return $ok;
1088 }
1089
1097 public function deleteUserResult($userresult)
1098 {
1099 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1100 'WHERE (user_result_pk = %d)', $userresult->getRecordId());
1101 $ok = $this->executeQuery($sql);
1102
1103 if ($ok) {
1104 $userresult->initialize();
1105 }
1106
1107 return $ok;
1108 }
1109
1110###
1111### Tool methods
1112###
1113
1121 public function loadTool($tool)
1122 {
1123 $ok = false;
1124 if (!is_null($tool->getRecordId())) {
1125 $sql = sprintf('SELECT tool_pk, name, consumer_key, secret, ' .
1126 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1127 'lti_version, signature_method, settings, enabled, ' .
1128 'enable_from, enable_until, last_access, created, updated ' .
1129 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1130 'WHERE tool_pk = %d', $tool->getRecordId());
1131 } elseif (!empty($tool->initiateLoginUrl)) {
1132 $sql = sprintf('SELECT tool_pk, name, consumer_key, secret, ' .
1133 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1134 'lti_version, signature_method, settings, enabled, ' .
1135 'enable_from, enable_until, last_access, created, updated ' .
1136 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1137 'WHERE initiate_login_url = %s', $this->escape($tool->initiateLoginUrl));
1138 } else {
1139 $sql = sprintf('SELECT tool_pk, name, consumer_key, secret, ' .
1140 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1141 'lti_version, signature_method, settings, enabled, ' .
1142 'enable_from, enable_until, last_access, created, updated ' .
1143 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1144 'WHERE consumer_key = %s', $this->escape($tool->getKey()));
1145 }
1146 $rsTool = $this->executeQuery($sql);
1147 if ($rsTool) {
1148 $row = pg_fetch_object($rsTool);
1149 if ($row) {
1150 $tool->setRecordId(intval($row->tool_pk));
1151 $tool->name = $row->name;
1152 $tool->setkey($row->consumer_key);
1153 $tool->secret = $row->secret;
1154 $tool->messageUrl = $row->message_url;
1155 $tool->initiateLoginUrl = $row->initiate_login_url;
1156 $tool->redirectionUris = Util::jsonDecode($row->redirection_uris, true);
1157 if (!is_array($tool->redirectionUris)) {
1158 $tool->redirectionUris = array();
1159 }
1160 $tool->rsaKey = $row->public_key;
1161 $tool->ltiVersion = $row->lti_version;
1162 $tool->signatureMethod = $row->signature_method;
1163 $settings = Util::jsonDecode($row->settings, true);
1164 if (!is_array($settings)) {
1165 $settings = array();
1166 }
1167 $tool->setSettings($settings);
1168 $tool->enabled = ($row->enabled === 't');
1169 $tool->enableFrom = null;
1170 if (!is_null($row->enable_from)) {
1171 $tool->enableFrom = strtotime($row->enable_from);
1172 }
1173 $tool->enableUntil = null;
1174 if (!is_null($row->enable_until)) {
1175 $tool->enableUntil = strtotime($row->enable_until);
1176 }
1177 $tool->lastAccess = null;
1178 if (!is_null($row->last_access)) {
1179 $tool->lastAccess = strtotime($row->last_access);
1180 }
1181 $tool->created = strtotime($row->created);
1182 $tool->updated = strtotime($row->updated);
1183 $this->fixToolSettings($tool, false);
1184 $ok = true;
1185 }
1186 }
1187
1188 return $ok;
1189 }
1190
1198 public function saveTool($tool)
1199 {
1200 $id = $tool->getRecordId();
1201 $enabled = ($tool->enabled) ? 'true' : 'false';
1202 $redirectionUrisValue = json_encode($tool->redirectionUris);
1203 $this->fixToolSettings($tool, true);
1204 $settingsValue = json_encode($tool->getSettings());
1205 $this->fixToolSettings($tool, false);
1206 $time = time();
1207 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
1208 $from = null;
1209 if (!is_null($tool->enableFrom)) {
1210 $from = date("{$this->dateFormat} {$this->timeFormat}", $tool->enableFrom);
1211 }
1212 $until = null;
1213 if (!is_null($tool->enableUntil)) {
1214 $until = date("{$this->dateFormat} {$this->timeFormat}", $tool->enableUntil);
1215 }
1216 $last = null;
1217 if (!is_null($tool->lastAccess)) {
1218 $last = date($this->dateFormat, $tool->lastAccess);
1219 }
1220 if (empty($id)) {
1221 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' (name, consumer_key, secret, ' .
1222 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1223 'lti_version, signature_method, settings, enabled, enable_from, enable_until, ' .
1224 'last_access, created, updated) ' .
1225 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', $this->escape($tool->name),
1226 $this->escape($tool->getKey()), $this->escape($tool->secret), $this->escape($tool->messageUrl),
1227 $this->escape($tool->initiateLoginUrl), $this->escape($redirectionUrisValue), $this->escape($tool->rsaKey),
1228 $this->escape($tool->ltiVersion), $this->escape($tool->signatureMethod), $this->escape($settingsValue), $enabled,
1229 $this->escape($from), $this->escape($until), $this->escape($last), $this->escape($now), $this->escape($now));
1230 } else {
1231 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' SET ' .
1232 'name = %s, consumer_key = %s, secret = %s, ' .
1233 'message_url = %s, initiate_login_url = %s, redirection_uris = %s, public_key = %s, ' .
1234 'lti_version = %s, signature_method = %s, settings = %s, enabled = %s, enable_from = %s, enable_until = %s, ' .
1235 'last_access = %s, updated = %s ' .
1236 'WHERE tool_pk = %d', $this->escape($tool->name), $this->escape($tool->getKey()), $this->escape($tool->secret),
1237 $this->escape($tool->messageUrl), $this->escape($tool->initiateLoginUrl), $this->escape($redirectionUrisValue),
1238 $this->escape($tool->rsaKey), $this->escape($tool->ltiVersion), $this->escape($tool->signatureMethod),
1239 $this->escape($settingsValue), $enabled, $this->escape($from), $this->escape($until), $this->escape($last),
1240 $this->escape($now), $tool->getRecordId());
1241 }
1242 $ok = $this->executeQuery($sql);
1243 if ($ok) {
1244 if (empty($id)) {
1245 $tool->setRecordId($this->insert_id());
1246 $tool->created = $time;
1247 }
1248 $tool->updated = $time;
1249 }
1250
1251 return $ok;
1252 }
1253
1261 public function deleteTool($tool)
1262 {
1263 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1264 'WHERE tool_pk = %d', $tool->getRecordId());
1265 $ok = $this->executeQuery($sql);
1266
1267 if ($ok) {
1268 $tool->initialize();
1269 }
1270
1271 return $ok;
1272 }
1273
1279 public function getTools()
1280 {
1281 $tools = array();
1282
1283 $sql = 'SELECT tool_pk, name, consumer_key, secret, ' .
1284 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1285 'lti_version, signature_method, settings, enabled, ' .
1286 'enable_from, enable_until, last_access, created, updated ' .
1287 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1288 'ORDER BY name';
1289 $rsTools = $this->executeQuery($sql);
1290 if ($rsTools) {
1291 while ($row = pg_fetch_object($rsTools)) {
1292 $tool = new Tool($this);
1293 $tool->setRecordId(intval($row->tool_pk));
1294 $tool->name = $row->name;
1295 $tool->setkey($row->consumer_key);
1296 $tool->secret = $row->secret;
1297 $tool->messageUrl = $row->message_url;
1298 $tool->initiateLoginUrl = $row->initiate_login_url;
1299 $tool->redirectionUris = Util::jsonDecode($row->redirection_uris, true);
1300 if (!is_array($tool->redirectionUris)) {
1301 $tool->redirectionUris = array();
1302 }
1303 $tool->rsaKey = $row->public_key;
1304 $tool->ltiVersion = $row->lti_version;
1305 $tool->signatureMethod = $row->signature_method;
1306 $settings = Util::jsonDecode($row->settings, true);
1307 if (!is_array($settings)) {
1308 $settings = array();
1309 }
1310 $tool->setSettings($settings);
1311 $tool->enabled = ($row->enabled === 't');
1312 $tool->enableFrom = null;
1313 if (!is_null($row->enable_from)) {
1314 $tool->enableFrom = strtotime($row->enable_from);
1315 }
1316 $tool->enableUntil = null;
1317 if (!is_null($row->enable_until)) {
1318 $tool->enableUntil = strtotime($row->enable_until);
1319 }
1320 $tool->lastAccess = null;
1321 if (!is_null($row->last_access)) {
1322 $tool->lastAccess = strtotime($row->last_access);
1323 }
1324 $tool->created = strtotime($row->created);
1325 $tool->updated = strtotime($row->updated);
1326 $this->fixToolSettings($tool, false);
1327 $tools[] = $tool;
1328 }
1329 pg_free_result($rsTools);
1330 }
1331
1332 return $tools;
1333 }
1334
1335###
1336### Other methods
1337###
1338
1344 private function insert_id()
1345 {
1346 $rsId = $this->executeQuery('SELECT lastval();');
1347 $row = pg_fetch_row($rsId);
1348 return intval($row[0]);
1349 }
1350
1362 public function escape($value, $addQuotes = true)
1363 {
1364 if (is_null($value)) {
1365 $value = 'null';
1366 } else {
1367 $value = pg_escape_string($this->db, $value);
1368 if ($addQuotes) {
1369 $value = "'{$value}'";
1370 }
1371 }
1372
1373 return $value;
1374 }
1375
1386 private function executeQuery($sql, $reportError = true)
1387 {
1388 $res = pg_query($this->db, $sql);
1389 if (($res === false) && $reportError) {
1390 Util::logError($sql . PHP_EOL . 'Error: ' . pg_last_error($this->db));
1391 } else {
1392 Util::logDebug($sql);
1393 }
1394
1395 return $res;
1396 }
1397
1398}
Class to represent an HTTP message.
Class to represent a platform context.
Definition Context.php:18
Class to represent an LTI Data Connector for PostgreSQL.
loadResourceLinkShareKey($shareKey)
Load resource link share key object.
escape($value, $addQuotes=true)
Escape a string for use in a database query.
saveUserResult($userresult)
Save user object.
loadContext($context)
Load context object.
savePlatform($platform)
Save platform object.
deletePlatform($platform)
Delete platform object.
saveAccessToken($accessToken)
Save access token object.
deletePlatformNonce($nonce)
Delete nonce object.
saveResourceLinkShareKey($shareKey)
Save resource link share key object.
saveContext($context)
Save context object.
loadAccessToken($accessToken)
Load access token object.
loadPlatform($platform)
Load platform object.
getUserResultSourcedIDsResourceLink($resourceLink, $localOnly, $idScope)
Get array of user objects.
getPlatforms()
Load all platforms from the database.
getSharesResourceLink($resourceLink)
Get array of shares defined for this resource link.
loadResourceLink($resourceLink)
Load resource link object.
saveResourceLink($resourceLink)
Save resource link object.
deleteContext($context)
Delete context object.
loadUserResult($userresult)
Load user object.
deleteUserResult($userresult)
Delete user object.
deleteResourceLinkShareKey($shareKey)
Delete resource link share key object.
deleteResourceLink($resourceLink)
Delete resource link object.
Class to provide a connection to a persistent store for LTI objects.
fixToolSettings($tool, $isSave)
Adjust the settings for any tool properties being stored as a setting value.
fixPlatformSettings($platform, $isSave)
Adjust the settings for any platform properties being stored as a setting value.
Class to represent a platform nonce.
Class to represent a platform.
Definition Platform.php:18
Class to represent a platform resource link share key.
Class to represent a platform resource link share.
Class to represent an LTI Tool.
Definition Tool.php:24
const ID_SCOPE_ID_ONLY
Use ID value only.
Definition Tool.php:34
Class to represent a platform user association with a resource link.
Class to implement utility methods.
Definition Util.php:15
static logError($message, $showSource=true)
Log an error message.
Definition Util.php:248
static jsonDecode($str, $associative=false)
Decode a JSON string.
Definition Util.php:560
static logDebug($message, $showSource=false)
Log a debug message.
Definition Util.php:274