AutorÃa | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Extends the IMS Tool provider library data connector for moodle.** @package enrol_lti* @copyright 2016 John Okely <john@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace enrol_lti;defined('MOODLE_INTERNAL') || die;use IMSGlobal\LTI\ToolProvider;use IMSGlobal\LTI\ToolProvider\ConsumerNonce;use IMSGlobal\LTI\ToolProvider\Context;use IMSGlobal\LTI\ToolProvider\DataConnector\DataConnector;use IMSGlobal\LTI\ToolProvider\ResourceLink;use IMSGlobal\LTI\ToolProvider\ResourceLinkShare;use IMSGlobal\LTI\ToolProvider\ResourceLinkShareKey;use IMSGlobal\LTI\ToolProvider\ToolConsumer;use IMSGlobal\LTI\ToolProvider\ToolProxy;use IMSGlobal\LTI\ToolProvider\User;use stdClass;/*** Extends the IMS Tool provider library data connector for moodle.** @package enrol_lti* @copyright 2016 John Okely <john@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class data_connector extends DataConnector {/** @var string Tool consumer table name. */protected $consumertable;/** @var string Context table name. */protected $contexttable;/** @var string Consumer nonce table name. */protected $noncetable;/** @var string Resource link table name. */protected $resourcelinktable;/** @var string Resource link share key table name. */protected $sharekeytable;/** @var string Tool proxy table name. */protected $toolproxytable;/** @var string User result table name. */protected $userresulttable;/*** data_connector constructor.*/public function __construct() {parent::__construct(null, 'enrol_lti_');// Set up table names.$this->consumertable = $this->dbTableNamePrefix . DataConnector::CONSUMER_TABLE_NAME;$this->contexttable = $this->dbTableNamePrefix . DataConnector::CONTEXT_TABLE_NAME;$this->noncetable = $this->dbTableNamePrefix . DataConnector::NONCE_TABLE_NAME;$this->resourcelinktable = $this->dbTableNamePrefix . DataConnector::RESOURCE_LINK_TABLE_NAME;$this->sharekeytable = $this->dbTableNamePrefix . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME;$this->toolproxytable = $this->dbTableNamePrefix . DataConnector::TOOL_PROXY_TABLE_NAME;$this->userresulttable = $this->dbTableNamePrefix . DataConnector::USER_RESULT_TABLE_NAME;}/*** Load tool consumer object.** @param ToolConsumer $consumer ToolConsumer object* @return boolean True if the tool consumer object was successfully loaded*/public function loadToolConsumer($consumer) {global $DB;$id = $consumer->getRecordId();$key = $consumer->getKey();$result = false;if (!empty($id)) {$result = $DB->get_record($this->consumertable, ['id' => $id]);} else if (!empty($key)) {$key256 = DataConnector::getConsumerKey($key);$result = $DB->get_record($this->consumertable, ['consumerkey256' => $key256]);}if ($result) {if (empty($key256) || empty($result->consumerkey) || ($key === $result->consumerkey)) {$this->build_tool_consumer_object($result, $consumer);return true;}}return false;}/*** Save tool consumer object.** @param ToolConsumer $consumer Consumer object* @return boolean True if the tool consumer object was successfully saved*/public function saveToolConsumer($consumer) {global $DB;$key = $consumer->getKey();$key256 = DataConnector::getConsumerKey($key);if ($key === $key256) {$key = null;}$protected = ($consumer->protected) ? 1 : 0;$enabled = ($consumer->enabled) ? 1 : 0;$profile = (!empty($consumer->profile)) ? json_encode($consumer->profile) : null;$settingsvalue = serialize($consumer->getSettings());$now = time();$consumer->updated = $now;$data = ['consumerkey256' => $key256,'consumerkey' => $key,'name' => $consumer->name,'secret' => $consumer->secret,'ltiversion' => $consumer->ltiVersion,'consumername' => $consumer->consumerName,'consumerversion' => $consumer->consumerVersion,'consumerguid' => $consumer->consumerGuid,'profile' => $profile,'toolproxy' => $consumer->toolProxy,'settings' => $settingsvalue,'protected' => $protected,'enabled' => $enabled,'enablefrom' => $consumer->enableFrom,'enableuntil' => $consumer->enableUntil,'lastaccess' => $consumer->lastAccess,'updated' => $consumer->updated,];$id = $consumer->getRecordId();if (empty($id)) {$consumer->created = $now;$data['created'] = $consumer->created;$id = $DB->insert_record($this->consumertable, (object) $data);if ($id) {$consumer->setRecordId($id);return true;}} else {$data['id'] = $id;return $DB->update_record($this->consumertable, (object) $data);}return false;}/*** Delete tool consumer object and related records.** @param ToolConsumer $consumer Consumer object* @return boolean True if the tool consumer object was successfully deleted*/public function deleteToolConsumer($consumer) {global $DB;$consumerpk = $consumer->getRecordId();$deletecondition = ['consumerid' => $consumerpk];// Delete any nonce values for this consumer.$DB->delete_records($this->noncetable, $deletecondition);// Delete any outstanding share keys for resource links for this consumer.$where = "resourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlWHERE rl.consumerid = :consumerid)";$DB->delete_records_select($this->sharekeytable, $where, $deletecondition);// Delete any outstanding share keys for resource links for contexts in this consumer.$where = "resourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlINNER JOIN {{$this->contexttable}} cON rl.contextid = c.idWHERE c.consumerid = :consumerid)";$DB->delete_records_select($this->sharekeytable, $where, $deletecondition);// Delete any users in resource links for this consumer.$where = "resourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlWHERE rl.consumerid = :consumerid)";$DB->delete_records_select($this->userresulttable, $where, $deletecondition);// Delete any users in resource links for contexts in this consumer.$where = "resourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlINNER JOIN {{$this->contexttable}} cON rl.contextid = c.idWHERE c.consumerid = :consumerid)";$DB->delete_records_select($this->userresulttable, $where, $deletecondition);// Update any resource links for which this consumer is acting as a primary resource link.$where = "primaryresourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlWHERE rl.consumerid = :consumerid)";$updaterecords = $DB->get_records_select($this->resourcelinktable, $where, $deletecondition);foreach ($updaterecords as $record) {$record->primaryresourcelinkid = null;$record->shareapproved = null;$DB->update_record($this->resourcelinktable, $record);}// Update any resource links for contexts in which this consumer is acting as a primary resource link.$where = "primaryresourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlINNER JOIN {{$this->contexttable}} cON rl.contextid = c.idWHERE c.consumerid = :consumerid)";$updaterecords = $DB->get_records_select($this->resourcelinktable, $where, $deletecondition);foreach ($updaterecords as $record) {$record->primaryresourcelinkid = null;$record->shareapproved = null;$DB->update_record($this->resourcelinktable, $record);}// Delete any resource links for contexts in this consumer.$where = "contextid IN (SELECT c.idFROM {{$this->contexttable}} cWHERE c.consumerid = :consumerid)";$DB->delete_records_select($this->resourcelinktable, $where, $deletecondition);// Delete any resource links for this consumer.$DB->delete_records($this->resourcelinktable, $deletecondition);// Delete any contexts for this consumer.$DB->delete_records($this->contexttable, $deletecondition);// Delete consumer.$DB->delete_records($this->consumertable, ['id' => $consumerpk]);$consumer->initialize();return true;}/*** Load all tool consumers from the database.* @return array*/public function getToolConsumers() {global $DB;$consumers = [];$rsconsumers = $DB->get_recordset($this->consumertable, null, 'name');foreach ($rsconsumers as $row) {$consumer = new ToolProvider\ToolConsumer($row->consumerkey, $this);$this->build_tool_consumer_object($row, $consumer);$consumers[] = $consumer;}$rsconsumers->close();return $consumers;}/** ToolProxy methods.*//*** Load the tool proxy from the database.** @param ToolProxy $toolproxy* @return bool*/public function loadToolProxy($toolproxy) {return false;}/*** Save the tool proxy to the database.** @param ToolProxy $toolproxy* @return bool*/public function saveToolProxy($toolproxy) {return false;}/*** Delete the tool proxy from the database.** @param ToolProxy $toolproxy* @return bool*/public function deleteToolProxy($toolproxy) {return false;}/** Context methods.*//*** Load context object.** @param Context $context Context object* @return boolean True if the context object was successfully loaded*/public function loadContext($context) {global $DB;if (!empty($context->getRecordId())) {$params = ['id' => $context->getRecordId()];} else {$params = ['consumerid' => $context->getConsumer()->getRecordId(),'lticontextkey' => $context->ltiContextId];}if ($row = $DB->get_record($this->contexttable, $params)) {$context->setRecordId($row->id);$context->setConsumerId($row->consumerid);$context->ltiContextId = $row->lticontextkey;$context->type = $row->type;$settings = unserialize($row->settings);if (!is_array($settings)) {$settings = array();}$context->setSettings($settings);$context->created = $row->created;$context->updated = $row->updated;return true;}return false;}/*** Save context object.** @param Context $context Context object* @return boolean True if the context object was successfully saved*/public function saveContext($context) {global $DB;$now = time();$context->updated = $now;$settingsvalue = serialize($context->getSettings());$id = $context->getRecordId();$consumerpk = $context->getConsumer()->getRecordId();$isinsert = empty($id);if ($isinsert) {$context->created = $now;$params = ['consumerid' => $consumerpk,'lticontextkey' => $context->ltiContextId,'type' => $context->type,'settings' => $settingsvalue,'created' => $context->created,'updated' => $context->updated,];$id = $DB->insert_record($this->contexttable, (object) $params);if ($id) {$context->setRecordId($id);return true;}} else {$data = (object) ['id' => $id,'contextid' => $consumerpk,'lticontextkey' => $context->ltiContextId,'type' => $context->type,'settings' => $settingsvalue,'updated' => $context->updated,];return $DB->update_record($this->contexttable, $data);}return false;}/*** Delete context object.** @param Context $context Context object* @return boolean True if the Context object was successfully deleted*/public function deleteContext($context) {global $DB;$contextid = $context->getRecordId();$params = ['id' => $contextid];// Delete any outstanding share keys for resource links for this context.$where = "resourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlWHERE rl.contextid = :id)";$DB->delete_records_select($this->sharekeytable, $where, $params);// Delete any users in resource links for this context.$DB->delete_records_select($this->userresulttable, $where, $params);// Update any resource links for which this consumer is acting as a primary resource link.$where = "primaryresourcelinkid IN (SELECT rl.idFROM {{$this->resourcelinktable}} rlWHERE rl.contextid = :id)";$updaterecords = $DB->get_records_select($this->resourcelinktable, $where, $params);foreach ($updaterecords as $record) {$record->primaryresourcelinkid = null;$record->shareapproved = null;$DB->update_record($this->resourcelinktable, $record);}// Delete any resource links for this context.$DB->delete_records($this->resourcelinktable, ['contextid' => $contextid]);// Delete context.$DB->delete_records($this->contexttable, $params);$context->initialize();return true;}/** ResourceLink methods*//*** Load resource link object.** @param ResourceLink $resourcelink ResourceLink object* @return boolean True if the resource link object was successfully loaded*/public function loadResourceLink($resourcelink) {global $DB;$resourceid = $resourcelink->getRecordId();if (!empty($resourceid)) {$params = ['id' => $resourceid];$row = $DB->get_record($this->resourcelinktable, $params);} else if (!empty($resourcelink->getContext())) {$params = ['contextid' => $resourcelink->getContext()->getRecordId(),'ltiresourcelinkkey' => $resourcelink->getId()];$row = $DB->get_record($this->resourcelinktable, $params);} else {$sql = "SELECT r.*FROM {{$this->resourcelinktable}} rLEFT OUTER JOIN {{$this->contexttable}} cON r.contextid = c.idWHERE (r.consumerid = ? OR c.consumerid = ?)AND ltiresourcelinkkey = ?";$params = [$resourcelink->getConsumer()->getRecordId(),$resourcelink->getConsumer()->getRecordId(),$resourcelink->getId()];$row = $DB->get_record_sql($sql, $params);}if ($row) {$resourcelink->setRecordId($row->id);if (!is_null($row->contextid)) {$resourcelink->setContextId($row->contextid);} else {$resourcelink->setContextId(null);}if (!is_null($row->consumerid)) {$resourcelink->setConsumerId($row->consumerid);} else {$resourcelink->setConsumerId(null);}$resourcelink->ltiResourceLinkId = $row->ltiresourcelinkkey;$settings = unserialize($row->settings);if (!is_array($settings)) {$settings = array();}$resourcelink->setSettings($settings);if (!is_null($row->primaryresourcelinkid)) {$resourcelink->primaryResourceLinkId = $row->primaryresourcelinkid;} else {$resourcelink->primaryResourceLinkId = null;}$resourcelink->shareApproved = (is_null($row->shareapproved)) ? null : ($row->shareapproved == 1);$resourcelink->created = $row->created;$resourcelink->updated = $row->updated;return true;}return false;}/*** Save resource link object.** @param ResourceLink $resourcelink Resource_Link object* @return boolean True if the resource link object was successfully saved*/public function saveResourceLink($resourcelink) {global $DB;if (is_null($resourcelink->shareApproved)) {$approved = null;} else if ($resourcelink->shareApproved) {$approved = 1;} else {$approved = 0;}if (empty($resourcelink->primaryResourceLinkId)) {$primaryresourcelinkid = null;} else {$primaryresourcelinkid = $resourcelink->primaryResourceLinkId;}$now = time();$resourcelink->updated = $now;$settingsvalue = serialize($resourcelink->getSettings());if (!empty($resourcelink->getContext())) {$consumerid = null;$contextid = $resourcelink->getContext()->getRecordId();} else if (!empty($resourcelink->getContextId())) {$consumerid = null;$contextid = $resourcelink->getContextId();} else {$consumerid = $resourcelink->getConsumer()->getRecordId();$contextid = null;}$id = $resourcelink->getRecordId();$data = ['consumerid' => $consumerid,'contextid' => $contextid,'ltiresourcelinkkey' => $resourcelink->getId(),'settings' => $settingsvalue,'primaryresourcelinkid' => $primaryresourcelinkid,'shareapproved' => $approved,'updated' => $resourcelink->updated,];$returnid = null;if (empty($id)) {$resourcelink->created = $now;$data['created'] = $resourcelink->created;$id = $DB->insert_record($this->resourcelinktable, (object) $data);if ($id) {$resourcelink->setRecordId($id);return true;}} else {$data['id'] = $id;return $DB->update_record($this->resourcelinktable, (object) $data);}return false;}/*** Delete resource link object.** @param ResourceLink $resourcelink ResourceLink object* @return boolean True if the resource link object and its related records were successfully deleted.* Otherwise, a DML exception is thrown.*/public function deleteResourceLink($resourcelink) {global $DB;$resourcelinkid = $resourcelink->getRecordId();// Delete any outstanding share keys for resource links for this consumer.$DB->delete_records($this->sharekeytable, ['resourcelinkid' => $resourcelinkid]);// Delete users.$DB->delete_records($this->userresulttable, ['resourcelinkid' => $resourcelinkid]);// Update any resource links for which this is the primary resource link.$records = $DB->get_records($this->resourcelinktable, ['primaryresourcelinkid' => $resourcelinkid]);foreach ($records as $record) {$record->primaryresourcelinkid = null;$DB->update_record($this->resourcelinktable, $record);}// Delete resource link.$DB->delete_records($this->resourcelinktable, ['id' => $resourcelinkid]);$resourcelink->initialize();return true;}/*** Get array of user objects.** Obtain an array of User objects for users with a result sourcedId. The array may include users from other* resource links which are sharing this resource link. It may also be optionally indexed by the user ID of a specified scope.** @param ResourceLink $resourcelink Resource link object* @param boolean $localonly True if only users within the resource link are to be returned* (excluding users sharing this resource link)* @param int $idscope Scope value to use for user IDs* @return array Array of User objects*/public function getUserResultSourcedIDsResourceLink($resourcelink, $localonly, $idscope) {global $DB;$users = [];$params = ['resourcelinkid' => $resourcelink->getRecordId()];// Where clause for the subquery.$subwhere = "(id = :resourcelinkid AND primaryresourcelinkid IS NULL)";if (!$localonly) {$subwhere .= " OR (primaryresourcelinkid = :resourcelinkid2 AND shareapproved = 1)";$params['resourcelinkid2'] = $resourcelink->getRecordId();}// The subquery.$subsql = "SELECT idFROM {{$this->resourcelinktable}}WHERE {$subwhere}";// Our main where clause.$where = "resourcelinkid IN ($subsql)";// Fields to be queried.$fields = 'id, ltiresultsourcedid, ltiuserkey, created, updated';// Fetch records.$rs = $DB->get_recordset_select($this->userresulttable, $where, $params, '', $fields);foreach ($rs as $row) {$user = User::fromResourceLink($resourcelink, $row->ltiuserkey);$user->setRecordId($row->id);$user->ltiResultSourcedId = $row->ltiresultsourcedid;$user->created = $row->created;$user->updated = $row->updated;if (is_null($idscope)) {$users[] = $user;} else {$users[$user->getId($idscope)] = $user;}}$rs->close();return $users;}/*** Get array of shares defined for this resource link.** @param ResourceLink $resourcelink ResourceLink object* @return array Array of ResourceLinkShare objects*/public function getSharesResourceLink($resourcelink) {global $DB;$shares = [];$params = ['primaryresourcelinkid' => $resourcelink->getRecordId()];$fields = 'id, shareapproved, consumerid';$records = $DB->get_records($this->resourcelinktable, $params, 'consumerid', $fields);foreach ($records as $record) {$share = new ResourceLinkShare();$share->resourceLinkId = $record->id;$share->approved = $record->shareapproved == 1;$shares[] = $share;}return $shares;}/** ConsumerNonce methods*//*** Load nonce object.** @param ConsumerNonce $nonce Nonce object* @return boolean True if the nonce object was successfully loaded*/public function loadConsumerNonce($nonce) {global $DB;// Delete any expired nonce values.$now = time();$DB->delete_records_select($this->noncetable, "expires <= ?", [$now]);// Load the nonce.$params = ['consumerid' => $nonce->getConsumer()->getRecordId(),'value' => $nonce->getValue()];$result = $DB->get_field($this->noncetable, 'value', $params);return !empty($result);}/*** Save nonce object.** @param ConsumerNonce $nonce Nonce object* @return boolean True if the nonce object was successfully saved*/public function saveConsumerNonce($nonce) {global $DB;$data = ['consumerid' => $nonce->getConsumer()->getRecordId(),'value' => $nonce->getValue(),'expires' => $nonce->expires];return $DB->insert_record($this->noncetable, (object) $data, false);}/** ResourceLinkShareKey methods.*//*** Load resource link share key object.** @param ResourceLinkShareKey $sharekey ResourceLink share key object* @return boolean True if the resource link share key object was successfully loaded*/public function loadResourceLinkShareKey($sharekey) {global $DB;// Clear expired share keys.$now = time();$where = "expires <= :expires";$DB->delete_records_select($this->sharekeytable, $where, ['expires' => $now]);// Load share key.$fields = 'resourcelinkid, autoapprove, expires';if ($sharekeyrecord = $DB->get_record($this->sharekeytable, ['sharekey' => $sharekey->getId()], $fields)) {if ($sharekeyrecord->resourcelinkid == $sharekey->resourceLinkId) {$sharekey->autoApprove = $sharekeyrecord->autoapprove == 1;$sharekey->expires = $sharekeyrecord->expires;return true;}}return false;}/*** Save resource link share key object.** @param ResourceLinkShareKey $sharekey Resource link share key object* @return boolean True if the resource link share key object was successfully saved*/public function saveResourceLinkShareKey($sharekey) {global $DB;if ($sharekey->autoApprove) {$approve = 1;} else {$approve = 0;}$expires = $sharekey->expires;$params = ['sharekey' => $sharekey->getId(),'resourcelinkid' => $sharekey->resourceLinkId,'autoapprove' => $approve,'expires' => $expires];return $DB->insert_record($this->sharekeytable, (object) $params, false);}/*** Delete resource link share key object.** @param ResourceLinkShareKey $sharekey Resource link share key object* @return boolean True if the resource link share key object was successfully deleted*/public function deleteResourceLinkShareKey($sharekey) {global $DB;$DB->delete_records($this->sharekeytable, ['sharekey' => $sharekey->getId()]);$sharekey->initialize();return true;}/** User methods*//*** Load user object.** @param User $user User object* @return boolean True if the user object was successfully loaded*/public function loadUser($user) {global $DB;$userid = $user->getRecordId();$fields = 'id, resourcelinkid, ltiuserkey, ltiresultsourcedid, created, updated';if (!empty($userid)) {$row = $DB->get_record($this->userresulttable, ['id' => $userid], $fields);} else {$resourcelinkid = $user->getResourceLink()->getRecordId();$userid = $user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY);$row = $DB->get_record_select($this->userresulttable,"resourcelinkid = ? AND ltiuserkey = ?",[$resourcelinkid, $userid],$fields);}if ($row) {$user->setRecordId($row->id);$user->setResourceLinkId($row->resourcelinkid);$user->ltiUserId = $row->ltiuserkey;$user->ltiResultSourcedId = $row->ltiresultsourcedid;$user->created = $row->created;$user->updated = $row->updated;return true;}return false;}/*** Save user object.** @param User $user User object* @return boolean True if the user object was successfully saved*/public function saveUser($user) {global $DB;$now = time();$isinsert = is_null($user->created);$user->updated = $now;$params = ['ltiresultsourcedid' => $user->ltiResultSourcedId,'updated' => $user->updated];if ($isinsert) {$params['resourcelinkid'] = $user->getResourceLink()->getRecordId();$params['ltiuserkey'] = $user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY);$user->created = $now;$params['created'] = $user->created;$id = $DB->insert_record($this->userresulttable, (object) $params);if ($id) {$user->setRecordId($id);return true;}} else {$params['id'] = $user->getRecordId();return $DB->update_record($this->userresulttable, (object) $params);}return false;}/*** Delete user object.** @param User $user User object* @return boolean True if the user object was successfully deleted*/public function deleteUser($user) {global $DB;$DB->delete_records($this->userresulttable, ['id' => $user->getRecordId()]);$user->initialize();return true;}/*** Fetches the list of Context objects that are linked to a ToolConsumer.** @param ToolConsumer $consumer* @return Context[]*/public function get_contexts_from_consumer(ToolConsumer $consumer) {global $DB;$contexts = [];$contextrecords = $DB->get_records($this->contexttable, ['consumerid' => $consumer->getRecordId()], '', 'lticontextkey');foreach ($contextrecords as $record) {$context = Context::fromConsumer($consumer, $record->lticontextkey);$contexts[] = $context;}return $contexts;}/*** Fetches a resource link record that is associated with a ToolConsumer.** @param ToolConsumer $consumer* @return ResourceLink*/public function get_resourcelink_from_consumer(ToolConsumer $consumer) {global $DB;$resourcelink = null;if ($resourcelinkrecord = $DB->get_record($this->resourcelinktable, ['consumerid' => $consumer->getRecordId()],'ltiresourcelinkkey')) {$resourcelink = ResourceLink::fromConsumer($consumer, $resourcelinkrecord->ltiresourcelinkkey);}return $resourcelink;}/*** Fetches a resource link record that is associated with a Context object.** @param Context $context* @return ResourceLink*/public function get_resourcelink_from_context(Context $context) {global $DB;$resourcelink = null;if ($resourcelinkrecord = $DB->get_record($this->resourcelinktable, ['contextid' => $context->getRecordId()],'ltiresourcelinkkey')) {$resourcelink = ResourceLink::fromContext($context, $resourcelinkrecord->ltiresourcelinkkey);}return $resourcelink;}/*** Fetches the list of ToolConsumer objects that are linked to a tool.** @param int $toolid* @return ToolConsumer[]*/public function get_consumers_mapped_to_tool($toolid) {global $DB;$consumers = [];$consumerrecords = $DB->get_records('enrol_lti_tool_consumer_map', ['toolid' => $toolid], '', 'consumerid');foreach ($consumerrecords as $record) {$consumers[] = ToolConsumer::fromRecordId($record->consumerid, $this);}return $consumers;}/*** Builds a ToolConsumer object from a record object from the DB.** @param stdClass $record The DB record object.* @param ToolConsumer $consumer*/protected function build_tool_consumer_object($record, ToolConsumer $consumer) {$consumer->setRecordId($record->id);$consumer->name = $record->name;$key = empty($record->consumerkey) ? $record->consumerkey256 : $record->consumerkey;$consumer->setKey($key);$consumer->secret = $record->secret;$consumer->ltiVersion = $record->ltiversion;$consumer->consumerName = $record->consumername;$consumer->consumerVersion = $record->consumerversion;$consumer->consumerGuid = $record->consumerguid;$consumer->profile = json_decode($record->profile ?? '');$consumer->toolProxy = $record->toolproxy;$settings = unserialize($record->settings);if (!is_array($settings)) {$settings = array();}$consumer->setSettings($settings);$consumer->protected = $record->protected == 1;$consumer->enabled = $record->enabled == 1;$consumer->enableFrom = null;if (!is_null($record->enablefrom)) {$consumer->enableFrom = $record->enablefrom;}$consumer->enableUntil = null;if (!is_null($record->enableuntil)) {$consumer->enableUntil = $record->enableuntil;}$consumer->lastAccess = null;if (!is_null($record->lastaccess)) {$consumer->lastAccess = $record->lastaccess;}$consumer->created = $record->created;$consumer->updated = $record->updated;}}