LTI Integration Library 4.10.3
PHP class library for building LTI integrations
 
Loading...
Searching...
No Matches
DataConnector_sqlsrv.php
1<?php
2
4
5use ceLTIc\LTI;
16
24###
25# NB This class assumes that a MS SQL Server 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 = sqlsrv_fetch_object($rsConsumer);
96 if ($row && ($allowMultiple || !sqlsrv_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 = (intval($row->protected) === 1);
121 $platform->enabled = (intval($row->enabled) === 1);
122 $platform->enableFrom = null;
123 if (!is_null($row->enable_from)) {
124 $platform->enableFrom = date_timestamp_get($row->enable_from);
125 }
126 $platform->enableUntil = null;
127 if (!is_null($row->enable_until)) {
128 $platform->enableUntil = date_timestamp_get($row->enable_until);
129 }
130 $platform->lastAccess = null;
131 if (!is_null($row->last_access)) {
132 $platform->lastAccess = date_timestamp_get($row->last_access);
133 }
134 $platform->created = date_timestamp_get($row->created);
135 $platform->updated = date_timestamp_get($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) ? 1 : 0;
155 $enabled = ($platform->enabled) ? 1 : 0;
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, %d, %d, %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 = %d, enabled = %d, 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 sk ' .
237 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
238 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
239 'WHERE rl.consumer_pk = %d', $platform->getRecordId());
240 $this->executeQuery($sql);
241
242// Delete any outstanding share keys for resource links for contexts in this consumer
243 $sql = sprintf('DELETE sk ' .
244 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
245 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
246 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
247 'WHERE c.consumer_pk = %d', $platform->getRecordId());
248 $this->executeQuery($sql);
249
250// Delete any users in resource links for this consumer
251 $sql = sprintf('DELETE u ' .
252 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
253 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
254 'WHERE rl.consumer_pk = %d', $platform->getRecordId());
255 $this->executeQuery($sql);
256
257// Delete any users in resource links for contexts in this consumer
258 $sql = sprintf('DELETE u ' .
259 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
260 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
261 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
262 'WHERE c.consumer_pk = %d', $platform->getRecordId());
263 $this->executeQuery($sql);
264
265// Update any resource links for which this consumer is acting as a primary resource link
266 $sql = sprintf('UPDATE prl ' .
267 'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .
268 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' prl ' .
269 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
270 'WHERE rl.consumer_pk = %d', $platform->getRecordId());
271 $ok = $this->executeQuery($sql);
272
273// Update any resource links for contexts in which this consumer is acting as a primary resource link
274 $sql = sprintf('UPDATE prl ' .
275 'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .
276 "FROM {$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 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
279 'WHERE c.consumer_pk = %d', $platform->getRecordId());
280 $ok = $this->executeQuery($sql);
281
282// Delete any resource links for this consumer
283 $sql = sprintf('DELETE rl ' .
284 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
285 'WHERE rl.consumer_pk = %d', $platform->getRecordId());
286 $this->executeQuery($sql);
287
288// Delete any resource links for contexts in this consumer
289 $sql = sprintf('DELETE rl ' .
290 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
291 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
292 'WHERE c.consumer_pk = %d', $platform->getRecordId());
293 $this->executeQuery($sql);
294
295// Delete any contexts for this consumer
296 $sql = sprintf('DELETE c ' .
297 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ' .
298 'WHERE c.consumer_pk = %d', $platform->getRecordId());
299 $this->executeQuery($sql);
300
301// Delete consumer
302 $sql = sprintf('DELETE c ' .
303 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' c ' .
304 'WHERE c.consumer_pk = %d', $platform->getRecordId());
305 $ok = $this->executeQuery($sql);
306
307 if ($ok) {
308 $platform->initialize();
309 }
310
311 return $ok;
312 }
313
319 public function getPlatforms()
320 {
321 $platforms = array();
322
323 $sql = 'SELECT consumer_pk, consumer_key, name, secret, ' .
324 'platform_id, client_id, deployment_id, public_key, ' .
325 'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
326 'profile, tool_proxy, settings, protected, enabled, ' .
327 'enable_from, enable_until, last_access, created, updated ' .
328 "FROM {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' ' .
329 'ORDER BY name';
330 $rsConsumers = $this->executeQuery($sql);
331 if ($rsConsumers) {
332 while ($row = sqlsrv_fetch_object($rsConsumers)) {
333 $platform = new Platform($this);
334 $platform->setRecordId(intval($row->consumer_pk));
335 $platform->name = $row->name;
336 $platform->setKey($row->consumer_key);
337 $platform->secret = $row->secret;
338 $platform->platformId = $row->platform_id;
339 $platform->clientId = $row->client_id;
340 $platform->deploymentId = $row->deployment_id;
341 $platform->rsaKey = $row->public_key;
342 $platform->ltiVersion = $row->lti_version;
343 $platform->signatureMethod = $row->signature_method;
344 $platform->consumerName = $row->consumer_name;
345 $platform->consumerVersion = $row->consumer_version;
346 $platform->consumerGuid = $row->consumer_guid;
347 $platform->profile = Util::jsonDecode($row->profile);
348 $platform->toolProxy = $row->tool_proxy;
349 $settings = Util::jsonDecode($row->settings, true);
350 if (!is_array($settings)) {
351 $settings = @unserialize($row->settings); // check for old serialized setting
352 }
353 if (!is_array($settings)) {
354 $settings = array();
355 }
356 $platform->setSettings($settings);
357 $platform->protected = (intval($row->protected) === 1);
358 $platform->enabled = (intval($row->enabled) === 1);
359 $platform->enableFrom = null;
360 if (!is_null($row->enable_from)) {
361 $platform->enableFrom = date_timestamp_get($row->enable_from);
362 }
363 $platform->enableUntil = null;
364 if (!is_null($row->enable_until)) {
365 $platform->enableUntil = date_timestamp_get($row->enable_until);
366 }
367 $platform->lastAccess = null;
368 if (!is_null($row->last_access)) {
369 $platform->lastAccess = date_timestamp_get($row->last_access);
370 }
371 $platform->created = date_timestamp_get($row->created);
372 $platform->updated = date_timestamp_get($row->updated);
373 $this->fixPlatformSettings($platform, false);
374 $platforms[] = $platform;
375 }
376 sqlsrv_free_stmt($rsConsumers);
377 }
378
379 return $platforms;
380 }
381
382###
383### Context methods
384###
385
393 public function loadContext($context)
394 {
395 $ok = false;
396 if (!is_null($context->getRecordId())) {
397 $sql = sprintf('SELECT context_pk, consumer_pk, title, lti_context_id, type, settings, created, updated ' .
398 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
399 'WHERE (context_pk = %d)', $context->getRecordId());
400 } else {
401 $sql = sprintf('SELECT context_pk, consumer_pk, title, lti_context_id, type, settings, created, updated ' .
402 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' ' .
403 'WHERE (consumer_pk = %d) AND (lti_context_id = %s)', $context->getPlatform()->getRecordId(),
404 $this->escape($context->ltiContextId));
405 }
406 $rsContext = $this->executeQuery($sql);
407 if ($rsContext) {
408 $row = sqlsrv_fetch_object($rsContext);
409 if ($row) {
410 $context->setRecordId(intval($row->context_pk));
411 $context->setPlatformId(intval($row->consumer_pk));
412 $context->title = $row->title;
413 $context->ltiContextId = $row->lti_context_id;
414 $context->type = $row->type;
415 $settings = Util::jsonDecode($row->settings, true);
416 if (!is_array($settings)) {
417 $settings = @unserialize($row->settings); // check for old serialized setting
418 }
419 if (!is_array($settings)) {
420 $settings = array();
421 }
422 $context->setSettings($settings);
423 $context->created = date_timestamp_get($row->created);
424 $context->updated = date_timestamp_get($row->updated);
425 $ok = true;
426 }
427 }
428
429 return $ok;
430 }
431
439 public function saveContext($context)
440 {
441 $time = time();
442 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
443 $settingsValue = json_encode($context->getSettings());
444 $id = $context->getRecordId();
445 $consumer_pk = $context->getPlatform()->getRecordId();
446 if (empty($id)) {
447 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' (consumer_pk, title, ' .
448 'lti_context_id, type, settings, created, updated) ' .
449 'VALUES (%d, %s, %s, %s, %s, %s, %s)', $consumer_pk, $this->escape($context->title),
450 $this->escape($context->ltiContextId), $this->escape($context->type), $this->escape($settingsValue),
451 $this->escape($now), $this->escape($now));
452 } else {
453 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' SET ' .
454 'title = %s, lti_context_id = %s, type = %s, settings = %s, ' .
455 'updated = %s' .
456 'WHERE (consumer_pk = %d) AND (context_pk = %d)', $this->escape($context->title),
457 $this->escape($context->ltiContextId), $this->escape($context->type), $this->escape($settingsValue),
458 $this->escape($now), $consumer_pk, $id);
459 }
460 $ok = $this->executeQuery($sql);
461 if ($ok) {
462 if (empty($id)) {
463 $context->setRecordId($this->insert_id());
464 $context->created = $time;
465 }
466 $context->updated = $time;
467 }
468
469 return $ok;
470 }
471
479 public function deleteContext($context)
480 {
481// Delete any outstanding share keys for resource links for this context
482 $sql = sprintf('DELETE sk ' .
483 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
484 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
485 'WHERE rl.context_pk = %d', $context->getRecordId());
486 $this->executeQuery($sql);
487
488// Delete any users in resource links for this context
489 $sql = sprintf('DELETE u ' .
490 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' u ' .
491 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
492 'WHERE rl.context_pk = %d', $context->getRecordId());
493 $this->executeQuery($sql);
494
495// Update any resource links for which this consumer is acting as a primary resource link
496 $sql = sprintf('UPDATE prl ' .
497 'SET prl.primary_resource_link_pk = null, prl.share_approved = null ' .
498 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' prl ' .
499 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
500 'WHERE rl.context_pk = %d', $context->getRecordId());
501 $ok = $this->executeQuery($sql);
502
503// Delete any resource links for this consumer
504 $sql = sprintf('DELETE rl ' .
505 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' rl ' .
506 'WHERE rl.context_pk = %d', $context->getRecordId());
507 $this->executeQuery($sql);
508
509// Delete context
510 $sql = sprintf('DELETE c ' .
511 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ', 'WHERE c.context_pk = %d',
512 $context->getRecordId());
513 $ok = $this->executeQuery($sql);
514 if ($ok) {
515 $context->initialize();
516 }
517
518 return $ok;
519 }
520
521###
522### ResourceLink methods
523###
524
532 public function loadResourceLink($resourceLink)
533 {
534 $ok = false;
535 if (!is_null($resourceLink->getRecordId())) {
536 $sql = sprintf('SELECT resource_link_pk, context_pk, consumer_pk, title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' .
537 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
538 'WHERE (resource_link_pk = %d)', $resourceLink->getRecordId());
539 } elseif (!is_null($resourceLink->getContext())) {
540 $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 ' .
541 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r ' .
542 'WHERE (r.lti_resource_link_id = %s) AND ((r.context_pk = %d) OR (r.consumer_pk IN (' .
543 'SELECT c.consumer_pk ' .
544 "FROM {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' c ' .
545 'WHERE (c.context_pk = %d))))', $this->escape($resourceLink->getId()), $resourceLink->getContext()->getRecordId(),
546 $resourceLink->getContext()->getRecordId());
547 } else {
548 $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 ' .
549 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' r LEFT OUTER JOIN ' .
550 $this->dbTableNamePrefix . static::CONTEXT_TABLE_NAME . ' c ON r.context_pk = c.context_pk ' .
551 ' WHERE ((r.consumer_pk = %d) OR (c.consumer_pk = %d)) AND (lti_resource_link_id = %s)',
552 $resourceLink->getPlatform()->getRecordId(), $resourceLink->getPlatform()->getRecordId(),
553 $this->escape($resourceLink->getId()));
554 }
555 $rsResourceLink = $this->executeQuery($sql);
556 if ($rsResourceLink) {
557 $row = sqlsrv_fetch_object($rsResourceLink);
558 if ($row) {
559 $resourceLink->setRecordId(intval($row->resource_link_pk));
560 if (!is_null($row->context_pk)) {
561 $resourceLink->setContextId(intval($row->context_pk));
562 } else {
563 $resourceLink->setContextId(null);
564 }
565 if (!is_null($row->consumer_pk)) {
566 $resourceLink->setPlatformId(intval($row->consumer_pk));
567 } else {
568 $resourceLink->setPlatformId(null);
569 }
570 $resourceLink->title = $row->title;
571 $resourceLink->ltiResourceLinkId = $row->lti_resource_link_id;
572 $settings = Util::jsonDecode($row->settings, true);
573 if (!is_array($settings)) {
574 $settings = @unserialize($row->settings); // check for old serialized setting
575 }
576 if (!is_array($settings)) {
577 $settings = array();
578 }
579 $resourceLink->setSettings($settings);
580 if (!is_null($row->primary_resource_link_pk)) {
581 $resourceLink->primaryResourceLinkId = intval($row->primary_resource_link_pk);
582 } else {
583 $resourceLink->primaryResourceLinkId = null;
584 }
585 $resourceLink->shareApproved = (is_null($row->share_approved)) ? null : (intval($row->share_approved) === 1);
586 $resourceLink->created = date_timestamp_get($row->created);
587 $resourceLink->updated = date_timestamp_get($row->updated);
588 $ok = true;
589 }
590 }
591
592 return $ok;
593 }
594
602 public function saveResourceLink($resourceLink)
603 {
604 if (is_null($resourceLink->shareApproved)) {
605 $approved = 'NULL';
606 } elseif ($resourceLink->shareApproved) {
607 $approved = '1';
608 } else {
609 $approved = '0';
610 }
611 if (empty($resourceLink->primaryResourceLinkId)) {
612 $primaryResourceLinkId = 'NULL';
613 } else {
614 $primaryResourceLinkId = strval($resourceLink->primaryResourceLinkId);
615 }
616 $time = time();
617 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
618 $settingsValue = json_encode($resourceLink->getSettings());
619 if (!is_null($resourceLink->getContext())) {
620 $consumerId = 'NULL';
621 $contextId = strval($resourceLink->getContext()->getRecordId());
622 } elseif (!is_null($resourceLink->getContextId())) {
623 $consumerId = 'NULL';
624 $contextId = strval($resourceLink->getContextId());
625 } else {
626 $consumerId = strval($resourceLink->getPlatform()->getRecordId());
627 $contextId = 'NULL';
628 }
629 $id = $resourceLink->getRecordId();
630 if (empty($id)) {
631 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' (consumer_pk, context_pk, ' .
632 'title, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated) ' .
633 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)', $consumerId, $contextId, $this->escape($resourceLink->title),
634 $this->escape($resourceLink->getId()), $this->escape($settingsValue), $primaryResourceLinkId, $approved,
635 $this->escape($now), $this->escape($now));
636 } elseif ($contextId !== 'NULL') {
637 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' SET ' .
638 'consumer_pk = %s, title = %s, lti_resource_link_id = %s, settings = %s, ' .
639 'primary_resource_link_pk = %s, share_approved = %s, updated = %s ' .
640 'WHERE (context_pk = %s) AND (resource_link_pk = %d)', $consumerId, $this->escape($resourceLink->title),
641 $this->escape($resourceLink->getId()), $this->escape($settingsValue), $primaryResourceLinkId, $approved,
642 $this->escape($now), $contextId, $id);
643 } else {
644 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' SET ' .
645 'context_pk = NULL, title = %s, lti_resource_link_id = %s, settings = %s, ' .
646 'primary_resource_link_pk = %s, share_approved = %s, updated = %s ' .
647 'WHERE (consumer_pk = %s) AND (resource_link_pk = %d)', $this->escape($resourceLink->title),
648 $this->escape($resourceLink->getId()), $this->escape($settingsValue), $primaryResourceLinkId, $approved,
649 $this->escape($now), $consumerId, $id);
650 }
651 $ok = $this->executeQuery($sql);
652 if ($ok) {
653 if (empty($id)) {
654 $resourceLink->setRecordId($this->insert_id());
655 $resourceLink->created = $time;
656 }
657 $resourceLink->updated = $time;
658 }
659
660 return $ok;
661 }
662
670 public function deleteResourceLink($resourceLink)
671 {
672// Delete any outstanding share keys for resource links for this consumer
673 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
674 'WHERE (resource_link_pk = %d)', $resourceLink->getRecordId());
675 $ok = $this->executeQuery($sql);
676
677// Delete users
678 if ($ok) {
679 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
680 'WHERE (resource_link_pk = %d)', $resourceLink->getRecordId());
681 $ok = $this->executeQuery($sql);
682 }
683
684// Update any resource links for which this is the primary resource link
685 if ($ok) {
686 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
687 'SET primary_resource_link_pk = NULL ' .
688 'WHERE (primary_resource_link_pk = %d)', $resourceLink->getRecordId());
689 $ok = $this->executeQuery($sql);
690 }
691
692// Delete resource link
693 if ($ok) {
694 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' ' .
695 'WHERE (resource_link_pk = %s)', $resourceLink->getRecordId());
696 $ok = $this->executeQuery($sql);
697 }
698
699 if ($ok) {
700 $resourceLink->initialize();
701 }
702
703 return $ok;
704 }
705
718 public function getUserResultSourcedIDsResourceLink($resourceLink, $localOnly, $idScope)
719 {
720 $userResults = array();
721
722 if ($localOnly) {
723 $sql = sprintf('SELECT u.user_result_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
724 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' AS u ' .
725 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .
726 'ON u.resource_link_pk = rl.resource_link_pk ' .
727 "WHERE (rl.resource_link_pk = %d) AND (rl.primary_resource_link_pk IS NULL)", $resourceLink->getRecordId());
728 } else {
729 $sql = sprintf('SELECT u.user_result_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
730 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' AS u ' .
731 "INNER JOIN {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .
732 'ON u.resource_link_pk = rl.resource_link_pk ' .
733 'WHERE ((rl.resource_link_pk = %d) AND (rl.primary_resource_link_pk IS NULL)) OR ' .
734 '((rl.primary_resource_link_pk = %d) AND (share_approved = 1))', $resourceLink->getRecordId(),
735 $resourceLink->getRecordId());
736 }
737 $rsUser = $this->executeQuery($sql);
738 if ($rsUser) {
739 while ($row = sqlsrv_fetch_object($rsUser)) {
740 $userresult = LTI\UserResult::fromResourceLink($resourceLink, $row->lti_user_id);
741 if (is_null($idScope)) {
742 $userResults[] = $userresult;
743 } else {
744 $userResults[$userresult->getId($idScope)] = $userresult;
745 }
746 }
747 }
748
749 return $userResults;
750 }
751
759 public function getSharesResourceLink($resourceLink)
760 {
761 $shares = array();
762
763 $sql = sprintf('SELECT c.consumer_name, r.resource_link_pk, r.title, r.share_approved ' .
764 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS r ' .
765 "INNER JOIN {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' AS c ON r.consumer_pk = c.consumer_pk ' .
766 'WHERE (r.primary_resource_link_pk = %d) ' .
767 'UNION ' .
768 'SELECT c2.consumer_name, r2.resource_link_pk, r2.title, r2.share_approved ' .
769 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_TABLE_NAME . ' AS r2 ' .
770 "INNER JOIN {$this->dbTableNamePrefix}" . static::CONTEXT_TABLE_NAME . ' AS x ON r2.context_pk = x.context_pk ' .
771 "INNER JOIN {$this->dbTableNamePrefix}" . static::PLATFORM_TABLE_NAME . ' AS c2 ON x.consumer_pk = c2.consumer_pk ' .
772 'WHERE (r2.primary_resource_link_pk = %d) ' .
773 'ORDER BY consumer_name, title', $resourceLink->getRecordId(), $resourceLink->getRecordId());
774 $rsShare = $this->executeQuery($sql);
775 if ($rsShare) {
776 while ($row = sqlsrv_fetch_object($rsShare)) {
777 $share = new LTI\ResourceLinkShare();
778 $share->consumerName = $row->consumer_name;
779 $share->resourceLinkId = intval($row->resource_link_pk);
780 $share->title = $row->title;
781 $share->approved = (intval($row->share_approved) === 1);
782 $shares[] = $share;
783 }
784 }
785
786 return $shares;
787 }
788
789###
790### PlatformNonce methods
791###
792
800 public function loadPlatformNonce($nonce)
801 {
802 if (parent::useMemcache()) {
803 $ok = parent::loadPlatformNonce($nonce);
804 } else {
805 $ok = false;
806
807// Delete any expired nonce values
808 $now = date("{$this->dateFormat} {$this->timeFormat}", time());
809 $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . " WHERE expires <= '{$now}'";
810 $this->executeQuery($sql);
811
812// Load the nonce
813 $sql = sprintf("SELECT value AS T FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' ' .
814 'WHERE (consumer_pk = %d) AND (value = %s)', $nonce->getPlatform()->getRecordId(), $this->escape($nonce->getValue()));
815 $rsNonce = $this->executeQuery($sql, false);
816 if ($rsNonce) {
817 if (sqlsrv_fetch_object($rsNonce)) {
818 $ok = true;
819 }
820 }
821 }
822
823 return $ok;
824 }
825
833 public function savePlatformNonce($nonce)
834 {
835 if (parent::useMemcache()) {
836 $ok = parent::savePlatformNonce($nonce);
837 } else {
838 $expires = date("{$this->dateFormat} {$this->timeFormat}", $nonce->expires);
839 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . " (consumer_pk, value, expires) VALUES (%d, %s, %s)",
840 $nonce->getPlatform()->getRecordId(), $this->escape($nonce->getValue()), $this->escape($expires));
841 $ok = $this->executeQuery($sql);
842 }
843
844 return $ok;
845 }
846
854 public function deletePlatformNonce($nonce)
855 {
856 if (parent::useMemcache()) {
857 $ok = parent::deletePlatformNonce($nonce);
858 } else {
859 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::NONCE_TABLE_NAME . ' ' .
860 'WHERE (consumer_pk = %d) AND (value = %s)', $nonce->getPlatform()->getRecordId(), $this->escape($nonce->getValue()));
861 $ok = $this->executeQuery($sql);
862 }
863
864 return $ok;
865 }
866
867###
868### AccessToken methods
869###
870
878 public function loadAccessToken($accessToken)
879 {
880 if (parent::useMemcache()) {
881 $ok = parent::loadAccessToken($accessToken);
882 } else {
883 $ok = false;
884 $consumer_pk = $accessToken->getPlatform()->getRecordId();
885 $sql = sprintf('SELECT scopes, token, expires, created, updated ' .
886 "FROM {$this->dbTableNamePrefix}" . static::ACCESS_TOKEN_TABLE_NAME . ' ' .
887 'WHERE (consumer_pk = %d)', $consumer_pk);
888 $rsAccessToken = $this->executeQuery($sql, false);
889 if ($rsAccessToken) {
890 $row = sqlsrv_fetch_object($rsAccessToken);
891 if ($row) {
892 $scopes = Util::jsonDecode($row->scopes, true);
893 if (!is_array($scopes)) {
894 $scopes = array();
895 }
896 $accessToken->scopes = $scopes;
897 $accessToken->token = $row->token;
898 $accessToken->expires = date_timestamp_get($row->expires);
899 $accessToken->created = date_timestamp_get($row->created);
900 $accessToken->updated = date_timestamp_get($row->updated);
901 $ok = true;
902 }
903 }
904 }
905
906 return $ok;
907 }
908
916 public function saveAccessToken($accessToken)
917 {
918 if (parent::useMemcache()) {
919 $ok = parent::saveAccessToken($accessToken);
920 } else {
921 $consumer_pk = $accessToken->getPlatform()->getRecordId();
922 $scopes = json_encode($accessToken->scopes, JSON_UNESCAPED_SLASHES);
923 $token = $accessToken->token;
924 $expires = date("{$this->dateFormat} {$this->timeFormat}", $accessToken->expires);
925 $time = time();
926 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
927 if (empty($accessToken->created)) {
928 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::ACCESS_TOKEN_TABLE_NAME . ' ' .
929 '(consumer_pk, scopes, token, expires, created, updated) ' .
930 'VALUES (%d, %s, %s, %s, %s, %s)', $consumer_pk, $this->escape($scopes), $this->escape($token),
931 $this->escape($expires), $this->escape($now), $this->escape($now));
932 } else {
933 $sql = sprintf('UPDATE ' . $this->dbTableNamePrefix . static::ACCESS_TOKEN_TABLE_NAME . ' ' .
934 'SET scopes = %s, token = %s, expires = %s, updated = %s WHERE consumer_pk = %d', $this->escape($scopes),
935 $this->escape($token), $this->escape($expires), $this->escape($now), $consumer_pk);
936 }
937 $ok = $this->executeQuery($sql);
938 }
939
940 return $ok;
941 }
942
943###
944### ResourceLinkShareKey methods
945###
946
954 public function loadResourceLinkShareKey($shareKey)
955 {
956 $ok = false;
957
958// Clear expired share keys
959 $now = date("{$this->dateFormat} {$this->timeFormat}", time());
960 $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . " WHERE expires <= '{$now}'";
961 $this->executeQuery($sql);
962
963// Load share key
964 $id = $shareKey->getId();
965 $sql = 'SELECT resource_link_pk, auto_approve, expires ' .
966 "FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
967 "WHERE share_key_id = '{$id}'";
968 $rsShareKey = $this->executeQuery($sql);
969 if ($rsShareKey) {
970 $row = sqlsrv_fetch_object($rsShareKey);
971 if ($row) {
972 $shareKey->resourceLinkId = intval($row->resource_link_pk);
973 $shareKey->autoApprove = (intval($row->auto_approve) === 1);
974 $shareKey->expires = date_timestamp_get($row->expires);
975 $ok = true;
976 }
977 }
978
979 return $ok;
980 }
981
989 public function saveResourceLinkShareKey($shareKey)
990 {
991 if ($shareKey->autoApprove) {
992 $approve = 1;
993 } else {
994 $approve = 0;
995 }
996 $expires = date("{$this->dateFormat} {$this->timeFormat}", $shareKey->expires);
997 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
998 '(share_key_id, resource_link_pk, auto_approve, expires) ' .
999 "VALUES (%s, %d, {$approve}, '{$expires}')", $this->escape($shareKey->getId()), $shareKey->resourceLinkId);
1000 $ok = $this->executeQuery($sql);
1001
1002 return $ok;
1003 }
1004
1012 public function deleteResourceLinkShareKey($shareKey)
1013 {
1014 $sql = "DELETE FROM {$this->dbTableNamePrefix}" . static::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . " WHERE share_key_id = '{$shareKey->getId()}'";
1015
1016 $ok = $this->executeQuery($sql);
1017
1018 if ($ok) {
1019 $shareKey->initialize();
1020 }
1021
1022 return $ok;
1023 }
1024
1025###
1026### UserResult methods
1027###
1028
1036 public function loadUserResult($userresult)
1037 {
1038 $ok = false;
1039 if (!is_null($userresult->getRecordId())) {
1040 $sql = sprintf('SELECT user_result_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1041 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1042 'WHERE (user_result_pk = %d)', $userresult->getRecordId());
1043 } else {
1044 $sql = sprintf('SELECT user_result_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1045 "FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1046 'WHERE (resource_link_pk = %d) AND (lti_user_id = %s)', $userresult->getResourceLink()->getRecordId(),
1047 $this->escape($userresult->getId(LTI\Tool::ID_SCOPE_ID_ONLY)));
1048 }
1049 $rsUserResult = $this->executeQuery($sql);
1050 if ($rsUserResult) {
1051 $row = sqlsrv_fetch_object($rsUserResult);
1052 if ($row) {
1053 $userresult->setRecordId(intval($row->user_result_pk));
1054 $userresult->setResourceLinkId(intval($row->resource_link_pk));
1055 $userresult->ltiUserId = $row->lti_user_id;
1056 $userresult->ltiResultSourcedId = $row->lti_result_sourcedid;
1057 $userresult->created = date_timestamp_get($row->created);
1058 $userresult->updated = date_timestamp_get($row->updated);
1059 $ok = true;
1060 }
1061 }
1062
1063 return $ok;
1064 }
1065
1073 public function saveUserResult($userresult)
1074 {
1075 $time = time();
1076 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
1077 if (is_null($userresult->created)) {
1078 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' (resource_link_pk, ' .
1079 'lti_user_id, lti_result_sourcedid, created, updated) ' .
1080 'VALUES (%d, %s, %s, %s, %s)', $userresult->getResourceLink()->getRecordId(),
1081 $this->escape($userresult->getId(LTI\Tool::ID_SCOPE_ID_ONLY)), $this->escape($userresult->ltiResultSourcedId),
1082 $this->escape($now), $this->escape($now));
1083 } else {
1084 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1085 'SET lti_result_sourcedid = %s, updated = %s ' .
1086 'WHERE (user_result_pk = %d)', $this->escape($userresult->ltiResultSourcedId), $this->escape($now),
1087 $userresult->getRecordId());
1088 }
1089 $ok = $this->executeQuery($sql);
1090 if ($ok) {
1091 if (is_null($userresult->created)) {
1092 $userresult->setRecordId($this->insert_id());
1093 $userresult->created = $time;
1094 }
1095 $userresult->updated = $time;
1096 }
1097
1098 return $ok;
1099 }
1100
1108 public function deleteUserResult($userresult)
1109 {
1110 $sql = sprintf("DELETE FROM {$this->dbTableNamePrefix}" . static::USER_RESULT_TABLE_NAME . ' ' .
1111 'WHERE (user_result_pk = %d)', $userresult->getRecordId());
1112 $ok = $this->executeQuery($sql);
1113
1114 if ($ok) {
1115 $userresult->initialize();
1116 }
1117
1118 return $ok;
1119 }
1120
1121###
1122### Tool methods
1123###
1124
1132 public function loadTool($tool)
1133 {
1134 $ok = false;
1135 if (!is_null($tool->getRecordId())) {
1136 $sql = sprintf('SELECT tool_pk, name, consumer_key, secret, ' .
1137 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1138 'lti_version, signature_method, settings, enabled, ' .
1139 'enable_from, enable_until, last_access, created, updated ' .
1140 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1141 'WHERE tool_pk = %d', $tool->getRecordId());
1142 } elseif (!empty($tool->initiateLoginUrl)) {
1143 $sql = sprintf('SELECT tool_pk, name, consumer_key, secret, ' .
1144 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1145 'lti_version, signature_method, settings, enabled, ' .
1146 'enable_from, enable_until, last_access, created, updated ' .
1147 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1148 'WHERE initiate_login_url = %s', $this->escape($tool->initiateLoginUrl));
1149 } else {
1150 $sql = sprintf('SELECT tool_pk, name, consumer_key, secret, ' .
1151 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1152 'lti_version, signature_method, settings, enabled, ' .
1153 'enable_from, enable_until, last_access, created, updated ' .
1154 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1155 'WHERE consumer_key = %s', $this->escape($tool->getKey()));
1156 }
1157 $rsTool = $this->executeQuery($sql);
1158 if ($rsTool) {
1159 $row = sqlsrv_fetch_object($rsTool);
1160 if ($row) {
1161 $tool->setRecordId(intval($row->tool_pk));
1162 $tool->name = $row->name;
1163 $tool->setkey($row->consumer_key);
1164 $tool->secret = $row->secret;
1165 $tool->messageUrl = $row->message_url;
1166 $tool->initiateLoginUrl = $row->initiate_login_url;
1167 $tool->redirectionUris = Util::jsonDecode($row->redirection_uris, true);
1168 if (!is_array($tool->redirectionUris)) {
1169 $tool->redirectionUris = array();
1170 }
1171 $tool->rsaKey = $row->public_key;
1172 $tool->ltiVersion = $row->lti_version;
1173 $tool->signatureMethod = $row->signature_method;
1174 $settings = Util::jsonDecode($row->settings, true);
1175 if (!is_array($settings)) {
1176 $settings = array();
1177 }
1178 $tool->setSettings($settings);
1179 $tool->enabled = (intval($row->enabled) === 1);
1180 $tool->enableFrom = null;
1181 if (!is_null($row->enable_from)) {
1182 $tool->enableFrom = date_timestamp_get($row->enable_from);
1183 }
1184 $tool->enableUntil = null;
1185 if (!is_null($row->enable_until)) {
1186 $tool->enableUntil = date_timestamp_get($row->enable_until);
1187 }
1188 $tool->lastAccess = null;
1189 if (!is_null($row->last_access)) {
1190 $tool->lastAccess = date_timestamp_get($row->last_access);
1191 }
1192 $tool->created = date_timestamp_get($row->created);
1193 $tool->updated = date_timestamp_get($row->updated);
1194 $this->fixToolSettings($tool, false);
1195 $ok = true;
1196 }
1197 }
1198
1199 return $ok;
1200 }
1201
1209 public function saveTool($tool)
1210 {
1211 $id = $tool->getRecordId();
1212 $enabled = ($tool->enabled) ? 1 : 0;
1213 $redirectionUrisValue = json_encode($tool->redirectionUris);
1214 $this->fixToolSettings($tool, true);
1215 $settingsValue = json_encode($tool->getSettings());
1216 $this->fixToolSettings($tool, false);
1217 $time = time();
1218 $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
1219 $from = null;
1220 if (!is_null($tool->enableFrom)) {
1221 $from = date("{$this->dateFormat} {$this->timeFormat}", $tool->enableFrom);
1222 }
1223 $until = null;
1224 if (!is_null($tool->enableUntil)) {
1225 $until = date("{$this->dateFormat} {$this->timeFormat}", $tool->enableUntil);
1226 }
1227 $last = null;
1228 if (!is_null($tool->lastAccess)) {
1229 $last = date($this->dateFormat, $tool->lastAccess);
1230 }
1231 if (empty($id)) {
1232 $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' (name, consumer_key, secret, ' .
1233 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1234 'lti_version, signature_method, settings, enabled, enable_from, enable_until, ' .
1235 'last_access, created, updated) ' .
1236 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s, %s, %s, %s, %s)', $this->escape($tool->name),
1237 $this->escape($tool->getKey()), $this->escape($tool->secret), $this->escape($tool->messageUrl),
1238 $this->escape($tool->initiateLoginUrl), $this->escape($redirectionUrisValue), $this->escape($tool->rsaKey),
1239 $this->escape($tool->ltiVersion), $this->escape($tool->signatureMethod), $this->escape($settingsValue), $enabled,
1240 $this->escape($from), $this->escape($until), $this->escape($last), $this->escape($now), $this->escape($now));
1241 } else {
1242 $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' SET ' .
1243 'name = %s, consumer_key = %s, secret= %s, ' .
1244 'message_url = %s, initiate_login_url = %s, redirection_uris = %s, public_key = %s, ' .
1245 'lti_version = %s, signature_method = %s, settings = %s, enabled = %d, enable_from = %s, enable_until = %s, ' .
1246 'last_access = %s, updated = %s ' .
1247 'WHERE tool_pk = %d', $this->escape($tool->name), $this->escape($tool->getKey()), $this->escape($tool->secret),
1248 $this->escape($tool->messageUrl), $this->escape($tool->initiateLoginUrl), $this->escape($redirectionUrisValue),
1249 $this->escape($tool->rsaKey), $this->escape($tool->ltiVersion), $this->escape($tool->signatureMethod),
1250 $this->escape($settingsValue), $enabled, $this->escape($from), $this->escape($until), $this->escape($last),
1251 $this->escape($now), $tool->getRecordId());
1252 }
1253 $ok = $this->executeQuery($sql);
1254 if ($ok) {
1255 if (empty($id)) {
1256 $tool->setRecordId($this->insert_id());
1257 $tool->created = $time;
1258 }
1259 $tool->updated = $time;
1260 }
1261
1262 return $ok;
1263 }
1264
1272 public function deleteTool($tool)
1273 {
1274 $sql = sprintf('DELETE t ' .
1275 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' t ' .
1276 'WHERE t.tool_pk = %d', $tool->getRecordId());
1277 $ok = $this->executeQuery($sql);
1278
1279 if ($ok) {
1280 $tool->initialize();
1281 }
1282
1283 return $ok;
1284 }
1285
1291 public function getTools()
1292 {
1293 $tools = array();
1294
1295 $sql = 'SELECT tool_pk, name, consumer_key, secret, ' .
1296 'message_url, initiate_login_url, redirection_uris, public_key, ' .
1297 'lti_version, signature_method, settings, enabled, ' .
1298 'enable_from, enable_until, last_access, created, updated ' .
1299 "FROM {$this->dbTableNamePrefix}" . static::TOOL_TABLE_NAME . ' ' .
1300 'ORDER BY name';
1301 $rsTools = $this->executeQuery($sql);
1302 if ($rsTools) {
1303 while ($row = sqlsrv_fetch_object($rsTools)) {
1304 $tool = new Tool($this);
1305 $tool->setRecordId(intval($row->tool_pk));
1306 $tool->name = $row->name;
1307 $tool->setkey($row->consumer_key);
1308 $tool->secret = $row->secret;
1309 $tool->messageUrl = $row->message_url;
1310 $tool->initiateLoginUrl = $row->initiate_login_url;
1311 $tool->redirectionUris = Util::jsonDecode($row->redirection_uris, true);
1312 if (!is_array($tool->redirectionUris)) {
1313 $tool->redirectionUris = array();
1314 }
1315 $tool->rsaKey = $row->public_key;
1316 $tool->ltiVersion = $row->lti_version;
1317 $tool->signatureMethod = $row->signature_method;
1318 $settings = Util::jsonDecode($row->settings, true);
1319 if (!is_array($settings)) {
1320 $settings = array();
1321 }
1322 $tool->setSettings($settings);
1323 $tool->enabled = (intval($row->enabled) === 1);
1324 $tool->enableFrom = null;
1325 if (!is_null($row->enable_from)) {
1326 $tool->enableFrom = date_timestamp_get($row->enable_from);
1327 }
1328 $tool->enableUntil = null;
1329 if (!is_null($row->enable_until)) {
1330 $tool->enableUntil = date_timestamp_get($row->enable_until);
1331 }
1332 $tool->lastAccess = null;
1333 if (!is_null($row->last_access)) {
1334 $tool->lastAccess = date_timestamp_get($row->last_access);
1335 }
1336 $tool->created = date_timestamp_get($row->created);
1337 $tool->updated = date_timestamp_get($row->updated);
1338 $this->fixToolSettings($tool, false);
1339 $tools[] = $tool;
1340 }
1341 sqlsrv_free_stmt($rsTools);
1342 }
1343
1344 return $tools;
1345 }
1346
1347###
1348### Other methods
1349###
1350
1362 public function escape($value, $addQuotes = true)
1363 {
1364 if (is_null($value)) {
1365 $value = 'null';
1366 } else {
1367 if ($addQuotes) {
1368 $value = str_replace("'", "''", $value);
1369 $value = "'{$value}'";
1370 }
1371 }
1372
1373 return $value;
1374 }
1375
1381 private function insert_id()
1382 {
1383 $id = 0;
1384 $sql = 'SELECT SCOPE_IDENTITY() AS insid;';
1385 $rsId = $this->executeQuery($sql);
1386 if ($rsId) {
1387 sqlsrv_fetch($rsId);
1388 $id = sqlsrv_get_field($rsId, 0, SQLSRV_PHPTYPE_INT);
1389 }
1390
1391 return $id;
1392 }
1393
1404 private function executeQuery($sql, $reportError = true)
1405 {
1406 $res = sqlsrv_query($this->db, $sql);
1407 if (($res === false) && $reportError) {
1408 Util::logError($sql . $this->errorListToString(sqlsrv_errors()));
1409 } else {
1410 Util::logDebug($sql);
1411 }
1412
1413 return $res;
1414 }
1415
1423 private function errorListToString($errorList)
1424 {
1425 $errors = '';
1426 if (is_array($errorList) && !empty($errorList)) {
1427 if (count($errorList) <= 1) {
1428 $sep = 'Error ';
1429 } else {
1430 $sep = 'Errors:' . PHP_EOL . ' ';
1431 }
1432 foreach ($errorList as $error) {
1433 $errors .= PHP_EOL . "{$sep}{$error['code']}/{$error['SQLSTATE']}: {$error['message']}";
1434 $sep = ' ';
1435 }
1436 }
1437
1438 return $errors;
1439 }
1440
1441}
Class to represent an HTTP message.
Class to represent a platform context.
Definition Context.php:18
Class to represent an LTI Data Connector for MS SQL Server.
loadResourceLinkShareKey($shareKey)
Load resource link share key object.
escape($value, $addQuotes=true)
Escape a string for use in a database query.
deletePlatform($platform)
Delete platform object.
saveAccessToken($accessToken)
Save access token object.
saveResourceLinkShareKey($shareKey)
Save resource link share key object.
loadAccessToken($accessToken)
Load access token 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.
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