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