ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilLTIDataConnector.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
29 use ceLTIc\LTI\User;
30 
31 class ilLTIDataConnector extends DataConnector
32 {
33  private ?\ilLogger $logger = null;
34 
36 
40  public function __construct()
41  {
42  global $DIC;
43  $this->database = $DIC->database();
44 
45  $this->logger = ilLoggerFactory::getLogger('ltis');
46  $this->db = null;
47  $this->dbTableNamePrefix = "";
48  }
49 
50  //
51  // next functions based on LTI Data Connector for MySQLi
52  //
58  public function loadPlatform(Platform $platform): bool
59  {
60  $ok = false;
61  $allowMultiple = false;
62  $id = $platform->getRecordId();
63  $query = 'SELECT consumer_pk, name, consumer_key, secret, ' .
64  'platform_id, client_id, deployment_id, public_key, ' .
65  'lti_version, signature_method, consumer_name, consumer_version, consumer_guid, ' .
66  'profile, tool_proxy, settings, protected, enabled, ' .
67  'enable_from, enable_until, last_access, created, updated, ext_consumer_id, ref_id ' .
68  'FROM lti2_consumer WHERE ';
69  if (!is_null($id)) {
70  $query .= 'consumer_pk = %s';
71  $types = array('integer');
72  $values = array($id);
73  } elseif (!empty($platform->platformId)) {
74  if (empty($platform->clientId)) {
75  $allowMultiple = true;
76  $query .= '(platform_id = %s)';
77  $types = array('text');
78  $values = array($platform->platformId);
79  } elseif (empty($platform->deploymentId)) {
80  $allowMultiple = true;
81  $query .= '(platform_id = %s) AND (client_id = %s)';
82  $types = array('text','text');
83  $values = array($platform->platformId, $platform->clientId);
84  } else {
85  $query .= '(platform_id = %s) AND (client_id = %s) AND (deployment_id = %s)';
86  $types = array('text','text','text');
87  $values = array($platform->platformId, $platform->clientId, $platform->deploymentId);
88  }
89  } elseif (!empty($platform->getKey())) {
90  $key = $platform->getKey();
91  $query .= 'consumer_key = %s';
92  $types = array('text');
93  $values = array($key);
94  } else {
95  return false;
96  }
97  // $ok = $this->executeQuery($sql, $stmt);
98  // if ($ok) {
99  // $rsConsumer = $stmt->get_result();
100  // $ok = $rsConsumer !== false;
101  // if ($ok) {
102  // $row = $rsConsumer->fetch_object();
103  // $ok = $row && ($allowMultiple || is_null($rsConsumer->fetch_object()));
104  // }
105  // }
106  // if ($ok) {
107  $res = $this->database->queryF($query, $types, $values);
108  while ($row = $this->database->fetchObject($res)) {
109  $platform->setRecordId(intval($row->consumer_pk));
110  $platform->name = $row->name;
111  $platform->setkey((string) $row->consumer_key);
112  $platform->secret = $row->secret;
113  $platform->platformId = $row->platform_id;
114  $platform->clientId = $row->client_id;
115  $platform->deploymentId = $row->deployment_id;
116  $platform->rsaKey = $row->public_key;
117  $platform->ltiVersion = isset($row->lti_version) ? LtiVersion::from($row->lti_version) : LtiVersion::V1;
118  $platform->signatureMethod = $row->signature_method;
119  $platform->consumerName = $row->consumer_name;
120  $platform->consumerVersion = $row->consumer_version;
121  $platform->consumerGuid = $row->consumer_guid;
122  $platform->profile = json_decode((string) $row->profile);
123  $platform->toolProxy = $row->tool_proxy;
124  $settings = json_decode($row->settings, true);
125  if (!is_array($settings)) {
126  $settings = @unserialize($row->settings); // check for old serialized setting
127  }
128  if (!is_array($settings)) {
129  $settings = array();
130  }
131  $platform->setSettings($settings);
132  $platform->protected = (intval($row->protected) === 1);
133  $platform->enabled = (intval($row->enabled) === 1);
134  $platform->enableFrom = null;
135  if (!is_null($row->enable_from)) {
136  $platform->enableFrom = strtotime($row->enable_from);
137  }
138  $platform->enableUntil = null;
139  if (!is_null($row->enable_until)) {
140  $platform->enableUntil = strtotime($row->enable_until);
141  }
142  $platform->lastAccess = null;
143  if (!is_null($row->last_access)) {
144  $platform->lastAccess = strtotime($row->last_access);
145  }
146  $platform->created = strtotime($row->created);
147  $platform->updated = strtotime($row->updated);
148  //ILIAS specific
149  $platform->setExtConsumerId(intval($row->ext_consumer_id));
150  $platform->setRefId((int) $row->ref_id);
151  // if ($platform->setTitle) $platform->setTitle($row->title);
152  // if ($platform->setDescription) $platform->setDescription($row->description);
153  // if ($platform->setPrefix) $platform->setPrefix($row->prefix);
154  // if ($platform->setPrefix) $platform->setLanguage($row->user_language);
155  // if ($platform->setPrefix) $platform->setRole($row->role);
156  // local_role_always_member
157  // default_skin
158  $this->fixPlatformSettings($platform, false);
159  $ok = true;
160  }
161  return $ok;
162  }
163  #######
164  // /**
165  // * Load tool consumer settings
166  // * @param ilLTIPlatform $platform
167  // * @return bool
168  // */
169  // public function loadObjectToolConsumerSettings(ilLTIPlatform $platform) : bool
170  // {
171  // $this->loadGlobalToolConsumerSettings($platform);
172  //
173  // $ilDB = $this->database;
174  //
175  // $query = 'SELECT * from lti2_consumer where id = ' . $ilDB->quote($platform->getExtConsumerId(), 'integer');
176  // $res = $ilDB->query($query);
177  // while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
178  // $platform->setTitle($row->title);
179  // $platform->setDescription($row->description);
180  // $platform->setPrefix($row->prefix);
181  // $platform->setLanguage($row->user_language);
182  // $platform->setRole($row->role);
183  // $platform->setActive((bool) $row->active);
184  // return true;
185  // }
186  // return false;
187  // }
188 
194  public function loadGlobalToolConsumerSettings(ilLTIPlatform $platform): bool
195  {
197 
198  $query = 'SELECT * from lti_ext_consumer where id = ' . $ilDB->quote($platform->getExtConsumerId(), 'integer');
199  $res = $ilDB->query($query);
200  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
201  $platform->setTitle($row->title);
202  $platform->setDescription($row->description);
203  $platform->setPrefix($row->prefix);
204  $platform->setLanguage($row->user_language);
205  $platform->setRole((int) $row->role);
206  $platform->setActive((bool) $row->active);
207  return true;
208  }
209  return false;
210  }
211 
212  // /**
213  // * Load extended tool consumer object with ILIAS extension.
214  // * @param Platform $platform Platform object
215  // * @return boolean True if the tool consumer object was successfully loaded
216  // */
217  // public function loadToolConsumerILIAS(ilLTIPlatform $platform) : bool
218  // {
219  // global $DIC;
220  // $ilDB = $DIC->database(); // TODO PHP8 Review: Move Global Access to Constructor
221  //
222  // $ok = false;
223  // $query = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .
224  // 'consumer_name, consumer_version, consumer_guid, ' .
225  // 'profile, tool_proxy, settings, protected, enabled, ' .
226  // 'enable_from, enable_until, last_access, created, updated, ' .
227  // 'ext_consumer_id, ref_id ' .
228  // #'title, description, prefix, user_language, role, local_role_always_member, default_skin ' .
229  // 'FROM lti2_consumer ' .
230  // #'FROM lti2_consumer, lti_ext_consumer ' .
231  // 'WHERE ';
232  // #'WHERE lti_ext_consumer.id = consumer_pk AND ';
233  // if (!empty($platform->getRecordId())) {
234  // $query .= 'consumer_pk = %s';
235  // $types = array('integer');
236  // $values = array($platform->getRecordId());
237  // } else {
238  // $query .= 'consumer_key256 = %s';
239  // $types = array('text');
240  // $key256 = ilLTIDataConnector::getConsumerKey($platform->getKey());
241  // $values = array($key256);
242  // }
243  // // $rsConsumer = mysql_query($sql);
244  // $res = $ilDB->queryF($query, $types, $values);
245  // // if ($rsConsumer) {
246  // while ($row = $ilDB->fetchObject($res)) {
247  // // while ($row = mysql_fetch_object($rsConsumer)) {
248  // if (empty($key256) || empty($row->consumer_key) || ($platform->getKey() === $row->consumer_key)) {
249  // $platform->setRecordId(intval($row->consumer_pk));
250  // $platform->name = $row->name;
251  // $platform->setkey(empty($row->consumer_key) ? $row->consumer_key256 : $row->consumer_key);
252  // $platform->secret = $row->secret;
253  // $platform->ltiVersion = $row->lti_version;
254  // $platform->consumerName = $row->consumer_name;
255  // $platform->consumerVersion = $row->consumer_version;
256  // $platform->consumerGuid = $row->consumer_guid;
257  // $platform->profile = json_decode((string) $row->profile); // TODO PHP8 Review: Undefined Property
258  // $platform->toolProxy = $row->tool_proxy; // TODO PHP8 Review: Undefined Property
259  // $settings = unserialize($row->settings);
260  // if (!is_array($settings)) {
261  // $settings = array();
262  // }
263  // $platform->setSettings($settings);
264  // $platform->protected = (intval($row->protected) === 1);
265  // $platform->enabled = (intval($row->enabled) === 1);
266  // $platform->enableFrom = null;
267  // if (!is_null($row->enable_from)) {
268  // $platform->enableFrom = strtotime($row->enable_from);
269  // }
270  // $platform->enableUntil = null;
271  // if (!is_null($row->enable_until)) {
272  // $platform->enableUntil = strtotime($row->enable_until);
273  // }
274  // $platform->lastAccess = null;
275  // if (!is_null($row->last_access)) {
276  // $platform->lastAccess = strtotime($row->last_access);
277  // }
278  // $platform->created = strtotime($row->created);
279  // $platform->updated = strtotime($row->updated);
280  //
281  // //ILIAS specific
282  // $platform->setExtConsumerId((int) $row->ext_consumer_id);
283  // $platform->setRefId((int) $row->ref_id);
284  // #$platform->setTitle($row->title);
285  // #$platform->setDescription($row->description);
286  // #$platform->setPrefix($row->prefix);
287  // #$platform->setLanguage($row->user_language);
288  // #$platform->setRole($row->role);
289  // // local_role_always_member
290  // // default_skin
291  //
292  // $ok = true;
293  // break;
294  // }
295  // // }
296  // // mysql_free_result($rsConsumer);
297  // }
298  //
299  // $this->loadGlobalToolConsumerSettings($platform);
300  // return $ok;
301  // }
302 
309  {
310  $db = $this->database;
311 
312  $query = 'SELECT consumer_pk from lti2_consumer ' .
313  'WHERE ext_consumer_id = ' . $db->quote($platform->getExtConsumerId(), 'integer') . ' ' .
314  'AND ref_id = ' . $db->quote($platform->getRefId(), 'integer');
315  $res = $db->query($query);
316  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
317  return (int) $row->consumer_pk;
318  }
319  return null;
320  }
321 
322  // /**
323  // * Save platform object.
324  // * @param Platform $platform Consumer object
325  // * @return bool True if the tool consumer object was successfully saved
326  // */
327  // public function saveToolConsumer(DataConnectorPlatform $platform) : bool
328  // {
329  // global $DIC;
330  // $ilDB = $DIC->database(); // TODO PHP8 Review: Move Global Access to Constructor
331  //
332  // $id = $platform->getRecordId();
333  // $key = $platform->getKey();
334  // $key256 = DataConnector::getConsumerKey($key);
335  // // $key256 = $this->getConsumerKey($key);
336  // if ($key === $key256) {
337  // $key = null;
338  // }
339  // $protected = ($platform->protected) ? 1 : 0;
340  // $enabled = ($platform->enabled) ? 1 : 0;
341  // $profile = (!empty($platform->profile)) ? json_encode($platform->profile) : null;
342  // $settingsValue = serialize($platform->getSettings());
343  // $time = time();
344  // $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
345  // $from = null;
346  // if (!is_null($platform->enableFrom)) {
347  // $from = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableFrom);
348  // }
349  // $until = null;
350  // if (!is_null($platform->enableUntil)) {
351  // $until = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableUntil);
352  // }
353  // $last = null;
354  // if (!is_null($platform->lastAccess)) {
355  // $last = date($this->dateFormat, $platform->lastAccess);
356  // }
357  //
358  // if (empty($id)) {
359  // $platform->setRecordId($ilDB->nextId('lti_ext_consumer'));
360  // $id = $platform->getRecordId();
361  // $platform->created = $time;
362  // $platform->updated = $time;
363  // if ($key256 == null) {
364  // $key256 = $id . DataConnector::getRandomString(10);
365  // }
366  //
367  // // $query = "INSERT INTO {$this->dbTableNamePrefix}" . $this->CONSUMER_TABLE_NAME . ' (consumer_key256, consumer_key, name, ' .
368  // $query = 'INSERT INTO lti2_consumer (consumer_key256, consumer_key, name, ' .
369  // 'secret, lti_version, consumer_name, consumer_version, consumer_guid, profile, tool_proxy, settings, protected, enabled, ' .
370  // 'enable_from, enable_until, last_access, created, updated, consumer_pk) ' .
371  // 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)';
372  // $types = array("text",
373  // "text",
374  // "text",
375  // "text",
376  // "text",
377  // "text",
378  // "text",
379  // "text",
380  // "text",
381  // "text",
382  // "text",
383  // "integer",
384  // "integer",
385  // "timestamp",
386  // "timestamp",
387  // "timestamp",
388  // "timestamp",
389  // "timestamp",
390  // "integer"
391  // );
392  // $values = array($key256,
393  // $key,
394  // $platform->name,
395  // $platform->secret,
396  // $platform->ltiVersion,
397  // $platform->consumerName,
398  // $platform->consumerVersion,
399  // $platform->consumerGuid,
400  // $profile,
401  // $platform->toolProxy, // TODO PHP8 Review: Undefined Property
402  // $settingsValue,
403  // $protected,
404  // $enabled,
405  // $from,
406  // $until,
407  // $last,
408  // $now,
409  // $now,
410  // $id
411  // );
412  // $ilDB->manipulateF($query, $types, $values);
413  // } else {
414  // $platform->updated = $time;
415  //
416  // $query = 'UPDATE lti2_consumer SET ' .
417  // 'consumer_key256 = %s, consumer_key = %s, name = %s, ' .
418  // 'secret= %s, lti_version = %s, consumer_name = %s, consumer_version = %s, consumer_guid = %s, ' .
419  // 'profile = %s, tool_proxy = %s, settings = %s, protected = %s, enabled = %s, ' .
420  // 'enable_from = %s, enable_until = %s, last_access = %s, updated = %s ' .
421  // 'WHERE consumer_pk = %s';
422  // $types = array("text",
423  // "text",
424  // "text",
425  // "text",
426  // "text",
427  // "text",
428  // "text",
429  // "text",
430  // "text",
431  // "text",
432  // "text",
433  // "integer",
434  // "integer",
435  // "timestamp",
436  // "timestamp",
437  // "timestamp",
438  // "timestamp",
439  // "integer"
440  // );
441  // $values = array($key256,
442  // $key,
443  // $platform->name,
444  // $platform->secret,
445  // $platform->ltiVersion,
446  // $platform->consumerName,
447  // $platform->consumerVersion,
448  // $platform->consumerGuid,
449  // $profile,
450  // $platform->toolProxy, // TODO PHP8 Review: Undefined Property
451  // $settingsValue,
452  // $protected,
453  // $enabled,
454  // $from,
455  // $until,
456  // $last,
457  // $now,
458  // $id
459  // );
460  // $ilDB->manipulateF($query, $types, $values);
461  // }
462  // return true;
463  // }
464 
468  public function saveGlobalToolConsumerSettings(ilLTIPlatform $platform): bool
469  {
471 
472  if (!$platform->getExtConsumerId()) {
473  // create
474  $new_id = $ilDB->nextId('lti_ext_consumer');
475  $query = 'INSERT INTO lti_ext_consumer (title, description, prefix, user_language, role, id, active) ' .
476  'VALUES (%s, %s, %s, %s, %s, %s, %s)';
477  $types = ["text", "text", "text", "text", "integer", "integer", 'integer'];
478  $values = [
479  $platform->getTitle(),
480  $platform->getDescription(),
481  $platform->getPrefix(),
482  $platform->getLanguage(),
483  $platform->getRole(),
484  $new_id,
485  $platform->getActive()
486  ];
487  $ilDB->manipulateF($query, $types, $values);
488  $platform->setExtConsumerId($new_id);
489  return true;
490  } else {
491  // update
492  $query = 'update lti_ext_consumer set ' .
493  'title = ' . $ilDB->quote($platform->getTitle(), 'text') . ', ' .
494  'description = ' . $ilDB->quote($platform->getDescription(), 'text') . ', ' .
495  'prefix = ' . $ilDB->quote($platform->getPrefix(), 'text') . ', ' .
496  'user_language = ' . $ilDB->quote($platform->getLanguage(), 'text') . ', ' .
497  'role = ' . $ilDB->quote($platform->getRole(), 'integer') . ', ' .
498  'active = ' . $ilDB->quote((int) $platform->getActive(), 'integer') . ' ' .
499  'where id = ' . $ilDB->quote($platform->getExtConsumerId(), 'integer');
500  $ilDB->manipulate($query);
501  return true;
502  }
503  }
504 
510  public function saveToolConsumerILIAS(ilLTIPlatform $platform): bool
511  {
513 
514  $id = $platform->getRecordId();
515  $key = $platform->getKey();
516  $protected = ($platform->protected) ? 1 : 0;
517  $enabled = ($platform->enabled) ? 1 : 0;
518  $profile = (!empty($platform->profile)) ? json_encode($platform->profile) : null;
519  // $settingsValue = '{}';
520  $this->fixPlatformSettings($platform, true);
521  $settingsValue = json_encode($platform->getSettings());
522  $this->fixPlatformSettings($platform, false);
523  $time = time();
524  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
525  $from = null;
526  if (!is_null($platform->enableFrom)) {
527  $from = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableFrom);
528  }
529  $until = null;
530  if (!is_null($platform->enableUntil)) {
531  $until = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableUntil);
532  }
533  $last = null;
534  if (!is_null($platform->lastAccess)) {
535  $last = date($this->dateFormat, $platform->lastAccess);
536  }
537 
538  $platform->name = $platform->getTitle();//50UK
539  if (empty($id)) {
540  $platform->setRecordId($ilDB->nextId('lti2_consumer'));
541  $id = $platform->getRecordId();
542  $platform->created = $time;
543  $platform->updated = $time;
544 
545  // $query = "INSERT INTO {$this->dbTableNamePrefix}" . $this->CONSUMER_TABLE_NAME . ' (consumer_key256, consumer_key, name, ' .
546  $query = 'INSERT INTO lti2_consumer (consumer_key, name, ' .
547  'secret, lti_version, consumer_name, consumer_version, consumer_guid, profile, tool_proxy, settings, protected, enabled, ' .
548  'enable_from, enable_until, last_access, created, updated, consumer_pk, ext_consumer_id, ref_id, platform_id, client_id, deployment_id, public_key) ' .
549  'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)';
550  $types = array("text",
551  "text",
552  "text",
553  "text",
554  "text",
555  "text",
556  "text",
557  "text",
558  "text",
559  "text",
560  "integer",
561  "integer",
562  "timestamp",
563  "timestamp",
564  "timestamp",
565  "timestamp",
566  "timestamp",
567  "integer",
568  'integer',
569  'integer',
570  "text",
571  "text",
572  "text",
573  "text"
574  );
575  $values = array($key,
576  $platform->name,
577  $platform->secret,
578  $platform->ltiVersion->value,
579  $platform->consumerName,
580  $platform->consumerVersion,
581  $platform->consumerGuid,
582  $profile,
583  $platform->toolProxy,
584  $settingsValue,
585  $protected,
586  $enabled,
587  $from,
588  $until,
589  $last,
590  $now,
591  $now,
592  $id,
593  $platform->getExtConsumerId(),
594  $platform->getRefId(),
595  (string) $platform->platformId,
596  $platform->clientId,
597  $platform->deploymentId,
598  $platform->rsaKey
599  );
600  $ilDB->manipulateF($query, $types, $values);
601  } else {
602  $platform->updated = $time;
603 
604  $query = 'UPDATE lti2_consumer SET ' .
605  'consumer_key = %s, name = %s, ' .
606  'secret= %s, lti_version = %s, consumer_name = %s, consumer_version = %s, consumer_guid = %s, ' .
607  'profile = %s, tool_proxy = %s, settings = %s, protected = %s, enabled = %s, ' .
608  'enable_from = %s, enable_until = %s, last_access = %s, updated = %s, ' .
609  'platform_id = %s, client_id = %s, deployment_id = %s, public_key = %s ' .
610  'WHERE consumer_pk = %s';
611  $types = array("text",
612  "text",
613  "text",
614  "text",
615  "text",
616  "text",
617  "text",
618  "text",
619  "text",
620  "text",
621  "integer",
622  "integer",
623  "timestamp",
624  "timestamp",
625  "timestamp",
626  "timestamp",
627  "text",
628  "text",
629  "text",
630  "text",
631  "integer"
632  );
633  $values = array($key,
634  $platform->name,
635  $platform->secret,
636  $platform->ltiVersion->value,
637  $platform->consumerName,
638  $platform->consumerVersion,
639  $platform->consumerGuid,
640  $profile,
641  $platform->toolProxy,
642  $settingsValue,
643  $protected,
644  $enabled,
645  $from,
646  $until,
647  $last,
648  $now,
649  $platform->platformId,
650  $platform->clientId,
651  $platform->deploymentId,
652  $platform->rsaKey,
653  $id
654  );
655  $ilDB->manipulateF($query, $types, $values);
656  }
657 
658  return true;
659  }
660 
664  public function deleteGlobalToolConsumerSettings(ilLTIPlatform $platform): bool
665  {
667 
668  $query = 'DELETE FROM lti_ext_consumer WHERE id = %s';
669  $types = array("integer");
670  $values = array($platform->getExtConsumerId());
671  $ilDB->manipulateF($query, $types, $values);
672 
673  $query = 'DELETE FROM lti_ext_consumer_otype WHERE consumer_id = %s';
674  $types = array("integer");
675  $values = array($platform->getExtConsumerId());
676  $ilDB->manipulateF($query, $types, $values);
677 
678  $query = 'DELETE FROM lti2_consumer WHERE ext_consumer_id = %s';
679  $types = array("integer");
680  $values = array($platform->getExtConsumerId());
681  $ilDB->manipulateF($query, $types, $values);
682 
683  // delete all assigned lti consumers
684  $platform->initialize();
685  return true;
686  }
687 
693  public function deleteToolConsumer(DataConnectorPlatform $platform): bool
694  {
696 
697  // Delete any nonce values for this consumer
698  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . ' WHERE consumer_pk = %s';
699  $types = array("integer");
700  $values = array($platform->getRecordId());
701  $ilDB->manipulateF($query, $types, $values);
702 
703  // Delete any outstanding share keys for resource links for this consumer
704  $query = 'DELETE sk ' .
705  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
706  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
707  'WHERE rl.consumer_pk = %s';
708  $types = array("integer");
709  $values = array($platform->getRecordId());
710  $ilDB->manipulateF($query, $types, $values);
711 
712  // Delete any outstanding share keys for resource links for contexts in this consumer
713  $query = 'DELETE sk ' .
714  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
715  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
716  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
717  'WHERE c.consumer_pk = %s';
718  $types = array("integer");
719  $values = array($platform->getRecordId());
720  $ilDB->manipulateF($query, $types, $values);
721 
722  // Delete any users in resource links for this consumer
723  $query = 'DELETE u ' .
724  "FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' u ' .
725  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
726  'WHERE rl.consumer_pk = %s';
727  $types = array("integer");
728  $values = array($platform->getRecordId());
729  $ilDB->manipulateF($query, $types, $values);
730 
731  // Delete any users in resource links for contexts in this consumer
732  $query = 'DELETE u ' .
733  "FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' u ' .
734  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
735  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
736  'WHERE c.consumer_pk = %s';
737  $types = array("integer");
738  $values = array($platform->getRecordId());
739  $ilDB->manipulateF($query, $types, $values);
740 
741  // Update any resource links for which this consumer is acting as a primary resource link
742  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' prl ' .
743  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
744  'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .
745  'WHERE rl.consumer_pk = %s';
746  $types = array("integer");
747  $values = array($platform->getRecordId());
748  $ilDB->manipulateF($query, $types, $values);
749 
750  // Update any resource links for contexts in which this consumer is acting as a primary resource link
751  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' prl ' .
752  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
753  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
754  'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .
755  'WHERE c.consumer_pk = %s';
756  $types = array("integer");
757  $values = array($platform->getRecordId());
758  $ilDB->manipulateF($query, $types, $values);
759 
760  // Delete any resource links for this consumer
761  $query = 'DELETE rl ' .
762  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ' .
763  'WHERE rl.consumer_pk = %s';
764  $types = array("integer");
765  $values = array($platform->getRecordId());
766  $ilDB->manipulateF($query, $types, $values);
767 
768  // Delete any resource links for contexts in this consumer
769  $query = 'DELETE rl ' .
770  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ' .
771  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .
772  'WHERE c.consumer_pk = %s';
773  $types = array("integer");
774  $values = array($platform->getRecordId());
775  $ilDB->manipulateF($query, $types, $values);
776 
777  // Delete any contexts for this consumer
778  $query = 'DELETE c ' .
779  "FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ' .
780  'WHERE c.consumer_pk = %s';
781  $types = array("integer");
782  $values = array($platform->getRecordId());
783  $ilDB->manipulateF($query, $types, $values);
784 
785  // Delete consumer
786  $query = 'DELETE c ' .
787  "FROM {$this->dbTableNamePrefix}" . DataConnector::PLATFORM_TABLE_NAME . ' c ' .
788  'WHERE c.consumer_pk = %s';
789  $types = array("integer");
790  $values = array($platform->getRecordId());
791  $ilDB->manipulateF($query, $types, $values);
792 
793  // if ($ok) {
794  $platform->initialize();
795  // }
796 
797  return true;
798  }
799 
804  public function getGlobalToolConsumerSettings(): array
805  {
807 
808  $platforms = array();
809  $query = 'SELECT * from lti_ext_consumer ';
810  $res = $ilDB->query($query);
811  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
812  $platform = new ilLTIPlatform(null, $this);
813  $platform->setExtConsumerId((int) $row->id);
814  $platform->setTitle($row->title);
815  $platform->setDescription($row->description);
816  $platform->setPrefix($row->prefix);
817  $platform->setLanguage($row->user_language);
818  $platform->setRole((int) $row->role);
819  $platform->setActive((bool) $row->active);
820  $platforms[] = $platform;
821  }
822  return $platforms;
823  }
824 
825 
826 
827  ###
828  # Load all tool consumers from the database
829  ###
830 
833  public function getToolConsumers(): array
834  {
836  $platforms = array();
837  $query = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .
838  'consumer_name, consumer_version, consumer_guid, ' .
839  'profile, tool_proxy, settings, protected, enabled, ' .
840  'enable_from, enable_until, last_access, created, updated, ' .
841  'title, description, prefix, user_language, role, local_role_always_member, default_skin ' .
842  'FROM lti2_consumer, lti_ext_consumer ' .
843  'WHERE lti_ext_consumer.id = consumer_pk';
844 
845  // $sql = 'SELECT consumer_pk, consumer_key, consumer_key, name, secret, lti_version, consumer_name, consumer_version, consumer_guid, ' .
846  // 'profile, tool_proxy, settings, ' .
847  // 'protected, enabled, enable_from, enable_until, last_access, created, updated ' .
848  // "FROM {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::CONSUMER_TABLE_NAME . ' ' .
849  // 'ORDER BY name';
850  // $rsConsumers = mysql_query($sql);
851  // if ($rsConsumers) {
852  // while ($row = mysql_fetch_object($rsConsumers)) {
853  $res = $ilDB->query($query);
854  // if ($rsConsumer) {
855  while ($row = $ilDB->fetchObject($res)) {
856  // $platform = new Tool\Platform($row->consumer_key, $this); //ACHTUNG: FEHLER IN BIBLIOTHEK; $row->consumer_key ist i.d.R. null
857  $platform = new ilLTIPlatform(null, $this);
858  $platform->setRecordId(intval($row->consumer_pk));
859  $platform->name = $row->name;
860  $platform->secret = $row->secret;
861  $platform->ltiVersion = $row->lti_version;
862  $platform->consumerName = $row->consumer_name;
863  $platform->consumerVersion = $row->consumer_version;
864  $platform->consumerGuid = $row->consumer_guid;
865  $platform->profile = json_decode($row->profile);
866  $platform->toolProxy = $row->tool_proxy;
867  $settings = unserialize($row->settings);
868  if (!is_array($settings)) {
869  $settings = array();
870  }
871  $platform->setSettings($settings);
872  $platform->protected = (intval($row->protected) === 1);
873  $platform->enabled = (intval($row->enabled) === 1);
874  $platform->enableFrom = null;
875  if (!is_null($row->enable_from)) {
876  $platform->enableFrom = strtotime($row->enable_from);
877  }
878  $platform->enableUntil = null;
879  if (!is_null($row->enable_until)) {
880  $platform->enableUntil = strtotime($row->enable_until);
881  }
882  $platform->lastAccess = null;
883  if (!is_null($row->last_access)) {
884  $platform->lastAccess = strtotime($row->last_access);
885  }
886  $platform->created = strtotime($row->created);
887  $platform->updated = strtotime($row->updated);
888  //ILIAS specific
889  $platform->setTitle($row->title);
890  $platform->setDescription($row->description);
891  $platform->setPrefix($row->prefix);
892  $platform->setLanguage($row->user_language);
893  $platform->setRole($row->role);
894  // local_role_always_member
895  // default_skin
896  $platform->setKey($row->consumer_key256);//ACHTUNG: hier müsste evtl. consumer_key sein
897  $platforms[] = $platform;
898  }
899  // mysql_free_result($rsConsumers);
900  // }
901 
902  return $platforms;
903  }
904  ###
905  ### ToolProxy methods
906  ###
907 
908  // ###
909  // # Load the tool proxy from the database
910  // ###
911  // public function loadToolProxy($toolProxy) : bool
912  // {
913  // return false;
914  // }
915  //
916  // ###
917  // # Save the tool proxy to the database
918  // ###
919  // public function saveToolProxy($toolProxy) : bool
920  // {
921  // return false;
922  // }
923  //
924  // ###
925  // # Delete the tool proxy from the database
926  // ###
927  // public function deleteToolProxy($toolProxy) : bool
928  // {
929  // return false;
930  // }
931 
932  ###
933  ### Context methods
934  ###
935 
941  public function loadContext(Context $context): bool
942  {
944  $ok = false;
945  if (!empty($context->getRecordId())) {
946  $query = 'SELECT context_pk, consumer_pk, lti_context_id, settings, created, updated ' .
947  "FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' ' .
948  'WHERE (context_pk = %s)';
949  $types = array("integer");
950  $values = array($context->getRecordId());
951  } else {
952  $query = 'SELECT context_pk, consumer_pk, lti_context_id, settings, created, updated ' .
953  "FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' ' .
954  'WHERE (consumer_pk = %s) AND (lti_context_id = %s)';
955  $types = array("integer", "text");
956  $values = array($context->getPlatform()->getRecordId(), $context->ltiContextId);
957  }
958  $rs_context = $ilDB->queryF($query, $types, $values);
959  if ($rs_context) {
960  $row = $ilDB->fetchObject($rs_context);
961  if ($row) {
962  $context->setRecordId(intval($row->context_pk));
963  $context->setPlatformId(intval($row->consumer_pk));
964  $context->ltiContextId = $row->lti_context_id;
965  $settings = json_decode($row->settings);
966  if (!is_array($settings)) {
967  $settings = array();
968  }
969  $context->setSettings($settings);
970  $context->created = strtotime($row->created);
971  $context->updated = strtotime($row->updated);
972  $ok = true;
973  }
974  }
975 
976  return $ok;
977  }
978 
984  public function saveContext(Context $context): bool
985  {
987 
988  $time = time();
989  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
990  //old: $settingsValue = serialize($context->getSettings());
991  $settingsValue = json_encode($context->getSettings());
992  $id = $context->getRecordId();
993  $platform_pk = $context->getPlatform()->getRecordId();
994  if (empty($id)) {
995  $context->setRecordId($ilDB->nextId(DataConnector::CONTEXT_TABLE_NAME));
996  $id = $context->getRecordId();
997  $context->created = $time;
998  //Check remove context_pk, add type
999  $query = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME .
1000  ' (context_pk, consumer_pk, lti_context_id, settings, created, updated) ' .
1001  'VALUES (%s, %s, %s, %s, %s, %s)';
1002  $types = array("integer", "integer", "text", "text", "timestamp", "timestamp");
1003  $values = array($id, $platform_pk, $context->ltiContextId, $settingsValue, $now, $now);
1004  } else {
1005  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' SET ' .
1006  'lti_context_id = %s, settings = %s, ' .
1007  'updated = %s' .
1008  'WHERE (consumer_pk = %s) AND (context_pk = %s)';
1009  $types = array("text", "text", "timestamp", "integer", "integer");
1010  $values = array($context->ltiContextId, $settingsValue, $now, $platform_pk, $id);
1011  }
1012  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1013  if ($ok) {
1014  $context->updated = $time;
1015  }
1016 
1017  return $ok;
1018  }
1019 
1025  public function deleteContext(Context $context): bool
1026  {
1028 
1029  // Delete any outstanding share keys for resource links for this context
1030  $query = 'DELETE sk ' .
1031  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' .
1032  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .
1033  'WHERE rl.context_pk = %s';
1034  $types = array("integer");
1035  $values = array($context->getRecordId());
1036  $ilDB->manipulateF($query, $types, $values);
1037 
1038  // Delete any users in resource links for this context
1039  $query = 'DELETE u ' .
1040  "FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' u ' .
1041  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .
1042  'WHERE rl.context_pk = %s';
1043  $types = array("integer");
1044  $values = array($context->getRecordId());
1045  $ilDB->manipulateF($query, $types, $values);
1046 
1047  // Update any resource links for which this consumer is acting as a primary resource link
1048  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' prl ' .
1049  "INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .
1050  'SET prl.primary_resource_link_pk = null, prl.share_approved = null ' .
1051  'WHERE rl.context_pk = %s';
1052  $types = array("integer");
1053  $values = array($context->getRecordId());
1054  $ilDB->manipulateF($query, $types, $values);
1055 
1056  // Delete any resource links for this consumer
1057  $query = 'DELETE rl ' .
1058  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ' .
1059  'WHERE rl.context_pk = %s';
1060  $types = array("integer");
1061  $values = array($context->getRecordId());
1062  $ilDB->manipulateF($query, $types, $values);
1063 
1064  // Delete context
1065  $query = 'DELETE c ' .
1066  "FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ' .
1067  'WHERE c.context_pk = %s';
1068  $types = array("integer");
1069  $values = array($context->getRecordId());
1070  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1071  if ($ok) {
1072  $context->initialize();
1073  }
1074 
1075  return $ok;
1076  }
1077 
1078  ###
1079  ### ResourceLink methods
1080  ###
1081 
1087  public function loadResourceLink(ResourceLink $resourceLink): bool
1088  {
1090 
1091  $ok = false;
1092  $id = $resourceLink->getRecordId();
1093  $rid = 0;
1094  $cid = 0;
1095  if (!is_null($id)) {
1096  $query = 'SELECT resource_link_pk, context_pk, consumer_pk, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' .
1097  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .
1098  'WHERE (resource_link_pk = %s)';
1099  $types = array("integer");
1100  $values = array($id);
1101  } elseif (!is_null($resourceLink->getContext())) {
1102  $rid = $resourceLink->getId();
1103  $cid = $resourceLink->getContext()->getRecordId();
1104  $query = 'SELECT resource_link_pk, context_pk, consumer_pk, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' .
1105  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' r ' .
1106  'WHERE (r.lti_resource_link_id = %s) AND ((r.context_pk = %s) OR (r.consumer_pk IN (' .
1107  'SELECT c.consumer_pk ' .
1108  "FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ' .
1109  'WHERE (c.context_pk = %s))))';
1110  $types = array("text", "integer", "integer");
1111  $values = array($rid, $cid, $cid);
1112  } else {
1113  $id = $resourceLink->getPlatform()->getRecordId();
1114  $rid = $resourceLink->getId();
1115  $query = 'SELECT r.resource_link_pk, r.context_pk, r.consumer_pk, r.lti_resource_link_id, r.settings, r.primary_resource_link_pk, r.share_approved, r.created, r.updated ' .
1116  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' r LEFT OUTER JOIN ' .
1117  $this->dbTableNamePrefix . DataConnector::CONTEXT_TABLE_NAME . ' c ON r.context_pk = c.context_pk ' .
1118  ' WHERE ((r.consumer_pk = %s) OR (c.consumer_pk = %s)) AND (lti_resource_link_id = %s)';
1119  $types = array("integer", "integer", "text");
1120  $values = array($id, $id, $rid);
1121  }
1122  $this->logger->debug("loadResourceLink id = " . $id . " rid =" . $rid . " cid =" . $cid . " query = " . $query);
1123  $rsContext = $ilDB->queryF($query, $types, $values);
1124  if ($rsContext) {
1125  $row = $ilDB->fetchObject($rsContext);
1126  if ($row) {
1127  $resourceLink->setRecordId(intval($row->resource_link_pk));
1128  if (!is_null($row->context_pk)) {
1129  $resourceLink->setContextId(intval($row->context_pk));
1130  } else {
1131  $resourceLink->setContextId(null);
1132  }
1133  if (!is_null($row->consumer_pk)) {
1134  $resourceLink->setPlatformId(intval($row->consumer_pk));
1135  } else {
1136  $resourceLink->setPlatformId(null);
1137  }
1138  //$resourceLink->title = $row->title;
1139  $resourceLink->ltiResourceLinkId = $row->lti_resource_link_id;
1140  $settings = json_decode($row->settings, true);
1141  if (!is_array($settings)) {
1142  $settings = @unserialize($row->settings); // check for old serialized setting
1143  }
1144  if (!is_array($settings)) {
1145  $settings = array();
1146  }
1147  $resourceLink->setSettings($settings);
1148  if (!is_null($row->primary_resource_link_pk)) {
1149  $resourceLink->primaryResourceLinkId = intval($row->primary_resource_link_pk);
1150  } else {
1151  $resourceLink->primaryResourceLinkId = null;
1152  }
1153  $resourceLink->shareApproved = (is_null($row->share_approved)) ? null : (intval($row->share_approved) === 1);
1154  $resourceLink->created = strtotime($row->created);
1155  $resourceLink->updated = strtotime($row->updated);
1156  } else {
1157  $ok = false;
1158  }
1159  }
1160 
1161 
1162  return $ok;
1163  }
1164 
1170  public function saveResourceLink(ResourceLink $resourceLink): bool
1171  {
1173 
1174  if (is_null($resourceLink->shareApproved)) {
1175  $approved = null;
1176  } elseif ($resourceLink->shareApproved) {
1177  $approved = '1';
1178  } else {
1179  $approved = '0';
1180  }
1181  if (empty($resourceLink->primaryResourceLinkId) || $resourceLink->primaryResourceLinkId == '0') {
1182  $primaryResourceLinkId = null;//'NULL';
1183  $resourceLink->primaryResourceLinkId = null; //Bug in 7: 0 instead of null
1184  } else {
1185  $primaryResourceLinkId = strval($resourceLink->primaryResourceLinkId);
1186  }
1187  $time = time();
1188  $now = date("{$this->dateFormat} {$this->timeFormat}", $time);
1189  $settingsValue = serialize($resourceLink->getSettings());
1190  if (!is_null($resourceLink->getContext())) {
1191  // $platformId = null;
1192  $platformId = strval($resourceLink->getPlatform()->getRecordId());
1193  $contextId = strval($resourceLink->getContext()->getRecordId());
1194  } elseif (!is_null($resourceLink->getContextId())) {
1195  // $platformId = null;
1196  $platformId = strval($resourceLink->getPlatform()->getRecordId());
1197  $contextId = strval($resourceLink->getContextId());
1198  } else {
1199  $platformId = strval($resourceLink->getPlatform()->getRecordId());
1200  $contextId = null;
1201  }
1202  $id = $resourceLink->getRecordId();
1203  if (empty($id)) {
1204  $resourceLink->setRecordId($ilDB->nextId(DataConnector::RESOURCE_LINK_TABLE_NAME));
1205  $id = $resourceLink->getRecordId();
1206  $resourceLink->created = $time;
1207  $query = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' (resource_link_pk, consumer_pk, context_pk, ' .
1208  'lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated) ' .
1209  'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)';
1210  $types = array("integer",
1211  "integer",
1212  "integer",
1213  "text",
1214  "text",
1215  "integer",
1216  "integer",
1217  "timestamp",
1218  "timestamp"
1219  );
1220  $values = array($id,
1221  $platformId,
1222  $contextId,
1223  $resourceLink->getId(),
1224  $settingsValue,
1225  $primaryResourceLinkId,
1226  $approved,
1227  $now,
1228  $now
1229  );
1230  } elseif (!is_null($contextId)) {
1231  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' SET ' .
1232  'consumer_pk = %s, lti_resource_link_id = %s, settings = %s, ' .
1233  'primary_resource_link_pk = %s, share_approved = %s, updated = %s ' .
1234  'WHERE (context_pk = %s) AND (resource_link_pk = %s)';
1235  $types = array("integer", "text", "text", "integer", "integer", "timestamp", "integer", "integer");
1236  $values = array($platformId,
1237  $resourceLink->getId(),
1238  $settingsValue,
1239  $primaryResourceLinkId,
1240  $approved,
1241  $now,
1242  $contextId,
1243  $id
1244  );
1245  } else {
1246  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' SET ' .
1247  'context_pk = %s, lti_resource_link_id = %s, settings = %s, ' .
1248  'primary_resource_link_pk = %s, share_approved = %s, updated = %s ' .
1249  'WHERE (consumer_pk = %s) AND (resource_link_pk = %s)';
1250  $types = array("integer", "text", "text", "integer", "integer", "timestamp", "integer", "integer");
1251  $values = array($contextId,
1252  $resourceLink->getId(),
1253  $settingsValue,
1254  $primaryResourceLinkId,
1255  $approved,
1256  $now,
1257  $platformId,
1258  $id
1259  );
1260  }
1261  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1262  $this->logger->debug('Update resource link with query: ' . $query);
1263  // $this->logger->logStack();
1264  $this->logger->dump($values, ilLogLevel::DEBUG);
1265  $this->logger->dump($ok, ilLogLevel::DEBUG);
1266 
1267  if ($ok) {
1268  $resourceLink->updated = $time;
1269  }
1270 
1271  return $ok;
1272  }
1273 
1279  public function deleteResourceLink(ResourceLink $resourceLink): bool
1280  {
1282 
1283  // Delete any outstanding share keys for resource links for this consumer
1284  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
1285  'WHERE (resource_link_pk = %s)';
1286  $types = array("integer");
1287  $values = array($resourceLink->getRecordId());
1288  $ok = $ilDB->manipulateF($query, $types, $values);
1289 
1290  // Delete users
1291  if ($ok) {
1292  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' .
1293  'WHERE (resource_link_pk = %s)';
1294  $types = array("integer");
1295  $values = array($resourceLink->getRecordId());
1296  $ok = $ilDB->manipulateF($query, $types, $values);
1297  }
1298 
1299  // Update any resource links for which this is the primary resource link
1300  if ($ok) {
1301  $query = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .
1302  'SET primary_resource_link_pk = NULL ' .
1303  'WHERE (primary_resource_link_pk = %s)';
1304  $types = array("integer");
1305  $values = array($resourceLink->getRecordId());
1306  $ok = $ilDB->manipulateF($query, $types, $values);
1307  }
1308 
1309  // Delete resource link
1310  if ($ok) {
1311  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .
1312  'WHERE (resource_link_pk = %s)';
1313  $types = array("integer");
1314  $values = array($resourceLink->getRecordId());
1315  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1316  }
1317 
1318  if ($ok) {
1319  $resourceLink->initialize();
1320  }
1321 
1322  return $ok;
1323  }
1324 
1335  ResourceLink $resourceLink,
1336  bool $localOnly,
1337  ?IdScope $idScope
1338  ): array {
1340 
1341  $users = array();
1342 
1343  // if ($localOnly) {
1344  // $query = 'SELECT u.user_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
1345  // "FROM {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::USER_RESULT_TABLE_NAME . ' AS u ' .
1346  // "INNER JOIN {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .
1347  // 'ON u.resource_link_pk = rl.resource_link_pk ' .
1348  // "WHERE (rl.resource_link_pk = %d) AND (rl.primary_resource_link_pk IS NULL)",
1349  // $resourceLink->getRecordId());
1350  // } else {
1351  // $query = 'SELECT u.user_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' .
1352  // "FROM {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::USER_RESULT_TABLE_NAME . ' AS u ' .
1353  // "INNER JOIN {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .
1354  // 'ON u.resource_link_pk = rl.resource_link_pk ' .
1355  // 'WHERE ((rl.resource_link_pk = %d) AND (rl.primary_resource_link_pk IS NULL)) OR ' .
1356  // '((rl.primary_resource_link_pk = %d) AND (share_approved = 1))',
1357  // $resourceLink->getRecordId(), $resourceLink->getRecordId());
1358  // }
1359  // $rsUser = mysql_query($sql);
1360  // if ($rsUser) {
1361  // while ($row = $ilDB->fetchObject($rsUser)) {
1362  // $user = Tool\User::fromResourceLink($resourceLink, $row->lti_user_id);
1363  // $user->setRecordId(intval($row->user_pk));
1364  // $user->ltiResultSourcedId = $row->lti_result_sourcedid;
1365  // $user->created = strtotime($row->created);
1366  // $user->updated = strtotime($row->updated);
1367  // if (is_null($idScope)) {
1368  // $users[] = $user;
1369  // } else {
1370  // $users[$user->getId($idScope)] = $user;
1371  // }
1372  // }
1373  // }
1374 
1375  return $users;
1376  }
1377 
1378  // /**
1379  // * Get array of shares defined for this resource link.
1380  // * @param ResourceLink $resourceLink Resource_Link object
1381  // * @return array Array of ResourceLinkShare objects
1382  // */
1383  // public function getSharesResourceLink(\ILIAS\LTI\Tool\ResourceLink $resourceLink) : array
1384  // {
1385  // global $DIC;
1386  // $ilDB = $DIC->database();
1387  //
1388  // $shares = array();
1389  //
1390  // $query = 'SELECT consumer_pk, resource_link_pk, share_approved ' .
1391  // "FROM {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .
1392  // 'WHERE (primary_resource_link_pk = %s) ' .
1393  // 'ORDER BY consumer_pk';
1394  // $types = array("integer");
1395  // $values = array($resourceLink->getRecordId());
1396  // $rsShare = $ilDB->queryF($query, $types, $values);
1397  // if ($rsShare) {
1398  // while ($row = $ilDB->fetchObject($rsShare)) {
1399  // $share = new Tool\ResourceLinkShare();
1400  // $share->resourceLinkId = intval($row->resource_link_pk);
1401  // $share->approved = (intval($row->share_approved) === 1);
1402  // $shares[] = $share;
1403  // }
1404  // }
1405  //
1406  // return $shares;
1407  // }
1408 
1409 
1410  ###
1411  ### PlatformNonce methods
1412  ###
1413 
1419  public function loadPlatformNonce(PlatformNonce $nonce): bool
1420  {
1422 
1423  $ok = true;
1424 
1425  // Delete any expired nonce values
1426  $now = date("{$this->dateFormat} {$this->timeFormat}", time());//PRÜFEN UK
1427  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . " WHERE expires <= %s";
1428  $types = array("timestamp");
1429  $values = array($now);
1430  $ilDB->manipulateF($query, $types, $values);
1431  // Load the nonce
1432  $query = "SELECT value AS T FROM {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . ' WHERE (consumer_pk = %s) AND (value = %s)';
1433  $types = array("integer", "text");
1434  $values = array($nonce->getPlatform()->getRecordId(), $nonce->getValue());
1435  $rs_nonce = $ilDB->queryF($query, $types, $values);
1436  if ($rs_nonce) {
1437  $row = $ilDB->fetchObject($rs_nonce);
1438  if (!$row) {
1439  $ok = false;
1440  }
1441  }
1442 
1443  return $ok;
1444  }
1445 
1451  public function savePlatformNonce(PlatformNonce $nonce): bool
1452  {
1454 
1455  $expires = date("{$this->dateFormat} {$this->timeFormat}", $nonce->expires);
1456  $query = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . " (consumer_pk, value, expires) VALUES (%s, %s, %s)";
1457  $types = array("integer", "text", "timestamp");
1458  $values = array($nonce->getPlatform()->getRecordId(), $nonce->getValue(), $expires);
1459  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1460 
1461  return $ok;
1462  }
1463 
1464 
1465  ###
1466  ### ResourceLinkShareKey methods
1467  ###
1468 
1474  // public function loadResourceLinkShareKey(\ILIAS\LTI\Tool\ResourceLinkShareKey $shareKey) : bool
1475  public function loadResourceLinkShareKey(ResourceLinkShareKey $shareKey): bool
1476  {
1478 
1479  $ok = false;
1480 
1481  // Clear expired share keys
1482  $now = date("{$this->dateFormat} {$this->timeFormat}", time());
1483  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . " WHERE expires <= '%s'";
1484  $types = array("timestamp");
1485  $values = array($now);
1486  $ilDB->manipulateF($query, $types, $values);
1487 
1488  // Load share key
1489  // $id = mysql_real_escape_string($shareKey->getId());//ACHTUNG UK utf8
1490  $id = $shareKey->getId();
1491  $query = 'SELECT resource_link_pk, auto_approve, expires ' .
1492  "FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
1493  "WHERE share_key_id = %s";
1494  $types = array("text");
1495  $values = array($id);
1496  $rsShareKey = $ilDB->queryF($query, $types, $values);
1497  if ($rsShareKey) {
1498  $row = $ilDB->fetchObject($rsShareKey);
1499  if ($row && (intval($row->resource_link_pk) === $shareKey->resourceLinkId)) {
1500  $shareKey->autoApprove = (intval($row->auto_approve) === 1);
1501  $shareKey->expires = strtotime($row->expires);
1502  $ok = true;
1503  }
1504  }
1505 
1506  return $ok;
1507  }
1508 
1514  // public function saveResourceLinkShareKey(\ILIAS\LTI\Tool\ResourceLinkShareKey $shareKey) : bool
1515  public function saveResourceLinkShareKey(ResourceLinkShareKey $shareKey): bool
1516  {
1518 
1519  if ($shareKey->autoApprove) {
1520  $approve = 1;
1521  } else {
1522  $approve = 0;
1523  }
1524  $expires = date("{$this->dateFormat} {$this->timeFormat}", $shareKey->expires);
1525  $query = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .
1526  '(share_key_id, resource_link_pk, auto_approve, expires) ' .
1527  "VALUES (%s, %s, %s, %s)";
1528  $types = array("text", "integer", "integer", "timestamp");
1529  $values = array($shareKey->getId(), $shareKey->resourceLinkId, $approve, $expires);
1530  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1531 
1532  return $ok;
1533  }
1534 
1540  public function deleteResourceLinkShareKey(ResourceLinkShareKey $shareKey): bool
1541  {
1543 
1544  $query = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . " WHERE share_key_id = %s";
1545  $types = array("text");
1546  $values = array($shareKey->getId());
1547  $ok = (bool) $ilDB->manipulateF($query, $types, $values);
1548 
1549  if ($ok) {
1550  $shareKey->initialize();
1551  }
1552 
1553  return $ok;
1554  }
1555 
1556 
1557  ###
1558  ### User methods
1559  ###
1560 
1566  public function loadUserResult(User $userresult): bool
1567  {
1569  $id = $userresult->getRecordId();
1570  if (!is_null($id)) {
1571  $query = 'SELECT user_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1572  'FROM ' . $this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME . ' ' .
1573  'WHERE user_pk = ' . $ilDB->quote($id, 'integer');
1574  } else {
1575  $rid = $userresult->getResourceLink()->getRecordId();
1576  $uid = $userresult->getId(ToolProvider\Tool::ID_SCOPE_ID_ONLY);
1577 
1578  $query = 'SELECT user_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' .
1579  'FROM ' . $this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME . ' ' .
1580  'WHERE resource_link_pk = ' . $ilDB->quote($rid, 'integer') . ' ' .
1581  'AND lti_user_id = ' . $ilDB->quote($uid, 'text');
1582  }
1583 
1584  $this->logger->debug('Loading user with query: ' . $query);
1585 
1586  $ok = false;
1587  try {
1588  $res = $ilDB->query($query);
1589  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1590  $userresult->setRecordId((int) $row->user_pk);
1591  $userresult->setResourceLinkId((int) $row->resource_link_pk);
1592  $userresult->ltiUserId = (string) $row->lti_user_id;
1593  $userresult->ltiResultSourcedId = (string) $row->lti_result_sourcedid;
1594  $userresult->created = strtotime($row->created);
1595  $userresult->updated = strtotime($row->updated);
1596  $ok = true;
1597  }
1598  } catch (ilDatabaseException $e) {
1599  $this->logger->error((string) $e);
1600  }
1601  return $ok;
1602  }
1603 
1609  public function saveUserResult(User $userresult): bool
1610  {
1612 
1613  $this->logger->info('Save user called with ' . $userresult->created);
1614 
1615  $time = time();
1616  $now = date($this->dateFormat . ' ' . $this->timeFormat, $time);
1617  if (is_null($userresult->created)) {
1618  // if (is_null($user->getRecordId())) {
1619  $userresult->setRecordId($ilDB->nextId($this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME));
1620  $userresult->created = $time;
1621  $rid = $userresult->getResourceLink()->getRecordId();
1622  $uid = $userresult->getId(ToolProvider\Tool::ID_SCOPE_ID_ONLY);
1623  $query = 'INSERT INTO ' . $this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME . ' ' .
1624  '(user_pk,resource_link_pk,lti_user_id, lti_result_sourcedid, created, updated) ' .
1625  'VALUES( ' .
1626  $ilDB->quote($userresult->getRecordId(), 'integer') . ', ' .
1627  $ilDB->quote($rid, 'integer') . ', ' .
1628  $ilDB->quote($uid, 'text') . ', ' .
1629  $ilDB->quote($userresult->ltiResultSourcedId, 'text') . ', ' .
1630  $ilDB->quote($now, 'text') . ', ' .
1631  $ilDB->quote($now, 'text') .
1632  ')';
1633  } else {
1634  $query = 'UPDATE ' . $this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME . ' ' .
1635  'SET lti_result_sourcedid = ' . $ilDB->quote($userresult->ltiResultSourcedId, 'text') . ', ' .
1636  'updated = ' . $ilDB->quote($now, 'text') . ' ' .
1637  'WHERE user_pk = ' . $ilDB->quote($userresult->getRecordId(), 'integer');
1638  }
1639 
1640  $this->logger->debug('Saving user data with query: ' . $query);
1641 
1642  $ok = false;
1643  try {
1644  $ilDB->manipulate($query);
1645  $userresult->updated = $time;
1646  $ok = true;
1647  } catch (ilDatabaseException $e) {
1648  $this->logger->error($e->getMessage());
1649  }
1650 
1651  return $ok;
1652  }
1653 
1659  public function deleteUser(DataConnectorUser $user): bool
1660  {
1662 
1663  $query = 'DELETE from ' . $this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME . ' ' .
1664  'WHERE user_pk = ' . $ilDB->quote($user->getRecordId(), 'integer');
1665 
1666  $ok = false;
1667  try {
1668  $ilDB->manipulate($query);
1669  $user->initialize();
1670  $ok = true;
1671  } catch (ilDatabaseException $e) {
1672  $this->logger->error((string) $e);
1673  }
1674  return $ok;
1675  }
1676 
1686  int $a_ref_id,
1687  string $a_lti_user,
1688  int $a_ext_consumer,
1689  ?ilDateTime $since = null
1690  ): array {
1691  $db = $this->database;
1692 
1693  $logger = ilLoggerFactory::getLogger('ltis');
1694 
1695  $query = 'select rl.resource_link_pk ' .
1696  'from lti2_user_result ur join lti2_resource_link rl on rl.resource_link_pk = ur.resource_link_pk ' .
1697  'join lti2_consumer c on rl.consumer_pk = c.consumer_pk ' .
1698  'join lti_ext_consumer ec on c.ext_consumer_id = ec.id ' .
1699  'where c.enabled = ' . $db->quote(1, 'integer') . ' ' .
1700  'and ref_id = ' . $db->quote($a_ref_id, 'integer') . ' ' .
1701  'and ur.lti_user_id = ' . $db->quote($a_lti_user, 'text') . ' ' .
1702  'and ec.id = ' . $db->quote($a_ext_consumer, 'integer');
1703  $logger->debug($query);
1704  $resource_links = [];
1705  try {
1706  $res = $db->query($query);
1707  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1708  $resource_links[] = $row->resource_link_pk;
1709  }
1710  } catch (ilDatabaseException $e) {
1711  $logger->error('Query execution failed with message: ' . $e->getMessage());
1712  }
1713  return $resource_links;
1714  }
1715 
1720  public function lookupResourcesForAllUsersSinceDate(ilDateTime $since): array
1721  {
1722  $db = $this->database;
1723  $logger = ilLoggerFactory::getLogger('ltis');
1724 
1725  $query = 'select lti_user_id, rl.resource_link_pk, ec.id, ref_id ' .
1726  'from lti2_resource_link rl join lti2_user_result ur on rl.resource_link_pk = ur.resource_link_pk ' .
1727  'join lti2_consumer c on rl.consumer_pk = c.consumer_pk ' .
1728  'join lti_ext_consumer ec on ext_consumer_id = ec.id ' .
1729  'where c.enabled = ' . $db->quote(1, 'integer') . ' ' .
1730  'and rl.updated > ' . $db->quote($since->get(IL_CAL_DATETIME), 'timestamp');
1731  $res = $db->query($query);
1732 
1733  $results = [];
1734  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
1735  $results[$row->id . '__' . $row->lti_user_id][] = $row->resource_link_pk . '__' . $row->ref_id;
1736  }
1737  return $results;
1738  }
1739 
1740  public static function getDataConnector(mixed $db = null, string $dbTableNamePrefix = '', string $type = ''): ilLTIDataConnector
1741  {
1742  $dataConnector = new ilLTIDataConnector();
1743  return $dataConnector;
1744  }
1745 }
get(int $a_format, string $a_format_str='', string $a_tz='')
get formatted date
setActive(bool $value)
$res
Definition: ltiservices.php:66
deleteContext(Context $context)
Delete context object.
getUserResultSourcedIDsResourceLink(ResourceLink $resourceLink, bool $localOnly, ?IdScope $idScope)
Get array of user objects.
$context
Definition: webdav.php:31
const IL_CAL_DATETIME
saveResourceLink(ResourceLink $resourceLink)
Save resource link object.
static getLogger(string $a_component_id)
Get component logger.
deleteResourceLinkShareKey(ResourceLinkShareKey $shareKey)
Delete resource link share key object.
deleteToolConsumer(DataConnectorPlatform $platform)
Delete tool consumer object.
quote($value, string $type)
saveUserResult(User $userresult)
Save user object.
loadPlatform(Platform $platform)
Load platform object.
loadUserResult(User $userresult)
Load user object.
static getDataConnector(mixed $db=null, string $dbTableNamePrefix='', string $type='')
lookupRecordIdByGlobalSettingsAndRefId(ilLTIPlatform $platform)
Load extended tool consumer object with ILIAS extension.
setRole(int $role_id)
setDescription(string $description)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
lookupResourcesForAllUsersSinceDate(ilDateTime $since)
loadResourceLinkShareKey(ResourceLinkShareKey $shareKey)
Load resource link share key object.
LTI provider for LTI launch.
savePlatformNonce(PlatformNonce $nonce)
Save nonce object.
loadResourceLink(ResourceLink $resourceLink)
Load resource link object.
global $DIC
Definition: shib_login.php:22
getGlobalToolConsumerSettings()
Get global consumer settings.
lookupResourcesForUserObjectRelation(int $a_ref_id, string $a_lti_user, int $a_ext_consumer, ?ilDateTime $since=null)
Lookup resources for user object relation.
$results
setExtConsumerId(int $a_id)
loadPlatformNonce(PlatformNonce $nonce)
Get array of shares defined for this resource link.
loadContext(Context $context)
Load context object.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
setLanguage(string $lang)
initialize()
Initialise the platform.
saveToolConsumerILIAS(ilLTIPlatform $platform)
Save extended tool consumer object with ILIAS extensions.
saveContext(Context $context)
Save context object.
saveResourceLinkShareKey(ResourceLinkShareKey $shareKey)
Save resource link share key object.
saveGlobalToolConsumerSettings(ilLTIPlatform $platform)
Save platform object.
Component logger with individual log levels by component id.
deleteResourceLink(ResourceLink $resourceLink)
Delete resource link object.
setTitle(string $title)
deleteUser(DataConnectorUser $user)
Delete user object.
loadGlobalToolConsumerSettings(ilLTIPlatform $platform)
Load tool consumer settings.
__construct()
ilLTIDataConnector constructor.
deleteGlobalToolConsumerSettings(ilLTIPlatform $platform)
Delete global tool consumer settings.
setPrefix(string $prefix)