AutorÃa | Ultima modificación | Ver Log |
<?phpnamespace IMSGlobal\LTI\ToolProvider\DataConnector;use IMSGlobal\LTI\ToolProvider;use IMSGlobal\LTI\ToolProvider\ConsumerNonce;use IMSGlobal\LTI\ToolProvider\Context;use IMSGlobal\LTI\ToolProvider\ResourceLink;use IMSGlobal\LTI\ToolProvider\ResourceLinkShareKey;use IMSGlobal\LTI\ToolProvider\ToolConsumer;use IMSGlobal\LTI\ToolProvider\User;use PDO;/*** Class to represent an LTI Data Connector for PDO connections** @author Stephen P Vickers <svickers@imsglobal.org>* @copyright IMS Global Learning Consortium Inc* @date 2016* @version 3.0.0* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0*/#[\AllowDynamicProperties]class DataConnector_pdo extends DataConnector{/*** Class constructor** @param object $db Database connection object* @param string $dbTableNamePrefix Prefix for database table names (optional, default is none)*/public function __construct($db, $dbTableNamePrefix = ''){parent::__construct($db, $dbTableNamePrefix);if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci') {$this->date_format = 'd-M-Y';}}###### ToolConsumer methods###/*** Load tool consumer object.** @param ToolConsumer $consumer ToolConsumer object** @return boolean True if the tool consumer object was successfully loaded*/public function loadToolConsumer($consumer){$ok = false;if (!empty($consumer->getRecordId())) {$sql = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .'consumer_name, consumer_version, consumer_guid, ' .'profile, tool_proxy, settings, protected, enabled, ' .'enable_from, enable_until, last_access, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONSUMER_TABLE_NAME . ' ' .'WHERE consumer_pk = :id';$query = $this->db->prepare($sql);$id = $consumer->getRecordId();$query->bindValue('id', $id, PDO::PARAM_INT);} else {$sql = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .'consumer_name, consumer_version, consumer_guid, ' .'profile, tool_proxy, settings, protected, enabled, ' .'enable_from, enable_until, last_access, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONSUMER_TABLE_NAME . ' ' .'WHERE consumer_key256 = :key256';$query = $this->db->prepare($sql);$key256 = DataConnector::getConsumerKey($consumer->getKey());$query->bindValue('key256', $key256, PDO::PARAM_STR);}if ($query->execute()) {while ($row = $query->fetch(PDO::FETCH_ASSOC)) {$row = array_change_key_case($row);if (empty($key256) || empty($row['consumer_key']) || ($consumer->getKey() === $row['consumer_key'])) {$consumer->setRecordId(intval($row['consumer_pk']));$consumer->name = $row['name'];$consumer->setkey(empty($row['consumer_key']) ? $row['consumer_key256'] : $row['consumer_key']);$consumer->secret = $row['secret'];$consumer->ltiVersion = $row['lti_version'];$consumer->consumerName = $row['consumer_name'];$consumer->consumerVersion = $row['consumer_version'];$consumer->consumerGuid = $row['consumer_guid'];$consumer->profile = json_decode($row['profile']);$consumer->toolProxy = $row['tool_proxy'];$settings = unserialize($row['settings']);if (!is_array($settings)) {$settings = array();}$consumer->setSettings($settings);$consumer->protected = (intval($row['protected']) === 1);$consumer->enabled = (intval($row['enabled']) === 1);$consumer->enableFrom = null;if (!is_null($row['enable_from'])) {$consumer->enableFrom = strtotime($row['enable_from']);}$consumer->enableUntil = null;if (!is_null($row['enable_until'])) {$consumer->enableUntil = strtotime($row['enable_until']);}$consumer->lastAccess = null;if (!is_null($row['last_access'])) {$consumer->lastAccess = strtotime($row['last_access']);}$consumer->created = strtotime($row['created']);$consumer->updated = strtotime($row['updated']);$ok = true;break;}}}return $ok;}/*** Save tool consumer object.** @param ToolConsumer $consumer Consumer object** @return boolean True if the tool consumer object was successfully saved*/public function saveToolConsumer($consumer){$id = $consumer->getRecordId();$key = $consumer->getKey();$key256 = $this->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());$time = time();$now = date("{$this->dateFormat} {$this->timeFormat}", $time);$from = null;if (!is_null($consumer->enableFrom)) {$from = date("{$this->dateFormat} {$this->timeFormat}", $consumer->enableFrom);}$until = null;if (!is_null($consumer->enableUntil)) {$until = date("{$this->dateFormat} {$this->timeFormat}", $consumer->enableUntil);}$last = null;if (!is_null($consumer->lastAccess)) {$last = date($this->dateFormat, $consumer->lastAccess);}if (empty($id)) {$sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::CONSUMER_TABLE_NAME . ' (consumer_key256, consumer_key, name, ' .'secret, lti_version, consumer_name, consumer_version, consumer_guid, profile, tool_proxy, settings, protected, enabled, ' .'enable_from, enable_until, last_access, created, updated) ' .'VALUES (:key256, :key, :name, :secret, :lti_version, :consumer_name, :consumer_version, :consumer_guid, :profile, :tool_proxy, :settings, ' .':protected, :enabled, :enable_from, :enable_until, :last_access, :created, :updated)';$query = $this->db->prepare($sql);$query->bindValue('key256', $key256, PDO::PARAM_STR);$query->bindValue('key', $key, PDO::PARAM_STR);$query->bindValue('name', $consumer->name, PDO::PARAM_STR);$query->bindValue('secret', $consumer->secret, PDO::PARAM_STR);$query->bindValue('lti_version', $consumer->ltiVersion, PDO::PARAM_STR);$query->bindValue('consumer_name', $consumer->consumerName, PDO::PARAM_STR);$query->bindValue('consumer_version', $consumer->consumerVersion, PDO::PARAM_STR);$query->bindValue('consumer_guid', $consumer->consumerGuid, PDO::PARAM_STR);$query->bindValue('profile', $profile, PDO::PARAM_STR);$query->bindValue('tool_proxy', $consumer->toolProxy, PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('protected', $protected, PDO::PARAM_INT);$query->bindValue('enabled', $enabled, PDO::PARAM_INT);$query->bindValue('enable_from', $from, PDO::PARAM_STR);$query->bindValue('enable_until', $until, PDO::PARAM_STR);$query->bindValue('last_access', $last, PDO::PARAM_STR);$query->bindValue('created', $now, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);} else {$sql = 'UPDATE ' . $this->dbTableNamePrefix . DataConnector::CONSUMER_TABLE_NAME . ' ' .'SET consumer_key256 = :key256, consumer_key = :key, name = :name, secret = :secret, lti_version = :lti_version, ' .'consumer_name = :consumer_name, consumer_version = :consumer_version, consumer_guid = :consumer_guid, ' .'profile = :profile, tool_proxy = :tool_proxy, settings = :settings, ' .'protected = :protected, enabled = :enabled, enable_from = :enable_from, enable_until = :enable_until, last_access = :last_access, updated = :updated ' .'WHERE consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('key256', $key256, PDO::PARAM_STR);$query->bindValue('key', $key, PDO::PARAM_STR);$query->bindValue('name', $consumer->name, PDO::PARAM_STR);$query->bindValue('secret', $consumer->secret, PDO::PARAM_STR);$query->bindValue('lti_version', $consumer->ltiVersion, PDO::PARAM_STR);$query->bindValue('consumer_name', $consumer->consumerName, PDO::PARAM_STR);$query->bindValue('consumer_version', $consumer->consumerVersion, PDO::PARAM_STR);$query->bindValue('consumer_guid', $consumer->consumerGuid, PDO::PARAM_STR);$query->bindValue('profile', $profile, PDO::PARAM_STR);$query->bindValue('tool_proxy', $consumer->toolProxy, PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('protected', $protected, PDO::PARAM_INT);$query->bindValue('enabled', $enabled, PDO::PARAM_INT);$query->bindValue('enable_from', $from, PDO::PARAM_STR);$query->bindValue('enable_until', $until, PDO::PARAM_STR);$query->bindValue('last_access', $last, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);$query->bindValue('id', $id, PDO::PARAM_INT);}$ok = $query->execute();if ($ok) {if (empty($id)) {$consumer->setRecordId(intval($this->db->lastInsertId()));$consumer->created = $time;}$consumer->updated = $time;}return $ok;}/*** Delete tool consumer object.** @param ToolConsumer $consumer Consumer object** @return boolean True if the tool consumer object was successfully deleted*/public function deleteToolConsumer($consumer){$id = $consumer->getRecordId();// Delete any nonce values for this consumer$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . ' WHERE consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any outstanding share keys for resource links for this consumer$sql = 'DELETE sk ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .'WHERE rl.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any outstanding share keys for resource links for contexts in this consumer$sql = 'DELETE sk ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .'WHERE c.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any users in resource links for this consumer$sql = 'DELETE u ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' u ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .'WHERE rl.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any users in resource links for contexts in this consumer$sql = 'DELETE u ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' u ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .'WHERE c.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Update any resource links for which this consumer is acting as a primary resource link$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' prl ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .'WHERE rl.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Update any resource links for contexts in which this consumer is acting as a primary resource link$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' prl ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .'SET prl.primary_resource_link_pk = NULL, prl.share_approved = NULL ' .'WHERE c.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any resource links for this consumer$sql = 'DELETE rl ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ' .'WHERE rl.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any resource links for contexts in this consumer$sql = 'DELETE rl ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ON rl.context_pk = c.context_pk ' .'WHERE c.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any contexts for this consumer$sql = 'DELETE c ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ' .'WHERE c.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete consumer$sql = 'DELETE c ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONSUMER_TABLE_NAME . ' c ' .'WHERE c.consumer_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$ok = $query->execute();if ($ok) {$consumer->initialize();}return $ok;}#### Load all tool consumers from the database###public function getToolConsumers(){$consumers = array();$sql = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' .'consumer_name, consumer_version, consumer_guid, ' .'profile, tool_proxy, settings, protected, enabled, ' .'enable_from, enable_until, last_access, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONSUMER_TABLE_NAME . ' ' .'ORDER BY name';$query = $this->db->prepare($sql);$ok = ($query !== FALSE);if ($ok) {$ok = $query->execute();}if ($ok) {while ($row = $query->fetch(PDO::FETCH_ASSOC)) {$row = array_change_key_case($row);$key = empty($row['consumer_key']) ? $row['consumer_key256'] : $row['consumer_key'];$consumer = new ToolProvider\ToolConsumer($key, $this);$consumer->setRecordId(intval($row['consumer_pk']));$consumer->name = $row['name'];$consumer->secret = $row['secret'];$consumer->ltiVersion = $row['lti_version'];$consumer->consumerName = $row['consumer_name'];$consumer->consumerVersion = $row['consumer_version'];$consumer->consumerGuid = $row['consumer_guid'];$consumer->profile = json_decode($row['profile']);$consumer->toolProxy = $row['tool_proxy'];$settings = unserialize($row['settings']);if (!is_array($settings)) {$settings = array();}$consumer->setSettings($settings);$consumer->protected = (intval($row['protected']) === 1);$consumer->enabled = (intval($row['enabled']) === 1);$consumer->enableFrom = null;if (!is_null($row['enable_from'])) {$consumer->enableFrom = strtotime($row['enable_from']);}$consumer->enableUntil = null;if (!is_null($row['enable_until'])) {$consumer->enableUntil = strtotime($row['enable_until']);}$consumer->lastAccess = null;if (!is_null($row['last_access'])) {$consumer->lastAccess = strtotime($row['last_access']);}$consumer->created = strtotime($row['created']);$consumer->updated = strtotime($row['updated']);$consumers[] = $consumer;}}return $consumers;}###### ToolProxy methods####### Load the tool proxy from the database###public function loadToolProxy($toolProxy){return false;}#### Save the tool proxy to the database###public function saveToolProxy($toolProxy){return false;}#### Delete the tool proxy from the database###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){$ok = false;if (!empty($context->getRecordId())) {$sql = 'SELECT context_pk, consumer_pk, lti_context_id, type, settings, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' ' .'WHERE (context_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $context->getRecordId(), PDO::PARAM_INT);} else {$sql = 'SELECT context_pk, consumer_pk, lti_context_id, type, settings, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' ' .'WHERE (consumer_pk = :cid) AND (lti_context_id = :ctx)';$query = $this->db->prepare($sql);$query->bindValue('cid', $context->getConsumer()->getRecordId(), PDO::PARAM_INT);$query->bindValue('ctx', $context->ltiContextId, PDO::PARAM_STR);}$ok = $query->execute();if ($ok) {$row = $query->fetch(PDO::FETCH_ASSOC);$ok = ($row !== FALSE);}if ($ok) {$row = array_change_key_case($row);$context->setRecordId(intval($row['context_pk']));$context->setConsumerId(intval($row['consumer_pk']));$context->ltiContextId = $row['lti_context_id'];$context->type = $row['type'];$settings = unserialize($row['settings']);if (!is_array($settings)) {$settings = array();}$context->setSettings($settings);$context->created = strtotime($row['created']);$context->updated = strtotime($row['updated']);}return $ok;}/*** Save context object.** @param Context $context Context object** @return boolean True if the context object was successfully saved*/public function saveContext($context){$time = time();$now = date("{$this->dateFormat} {$this->timeFormat}", $time);$settingsValue = serialize($context->getSettings());$id = $context->getRecordId();$consumer_pk = $context->getConsumer()->getRecordId();if (empty($id)) {$sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' (consumer_pk, lti_context_id, ' .'type, settings, created, updated) ' .'VALUES (:cid, :ctx, :type, :settings, :created, :updated)';$query = $this->db->prepare($sql);$query->bindValue('cid', $consumer_pk, PDO::PARAM_INT);$query->bindValue('ctx', $context->ltiContextId, PDO::PARAM_STR);$query->bindValue('type', $context->type, PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('created', $now, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);} else {$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' SET ' .'lti_context_id = :ctx, type = :type, settings = :settings, '.'updated = :updated ' .'WHERE (consumer_pk = :cid) AND (context_pk = :ctxid)';$query = $this->db->prepare($sql);$query->bindValue('ctx', $context->ltiContextId, PDO::PARAM_STR);$query->bindValue('type', $context->type, PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);$query->bindValue('cid', $consumer_pk, PDO::PARAM_INT);$query->bindValue('ctxid', $id, PDO::PARAM_INT);}$ok = $query->execute();if ($ok) {if (empty($id)) {$context->setRecordId(intval($this->db->lastInsertId()));$context->created = $time;}$context->updated = $time;}return $ok;}/*** Delete context object.** @param Context $context Context object** @return boolean True if the Context object was successfully deleted*/public function deleteContext($context){$id = $context->getRecordId();// Delete any outstanding share keys for resource links for this context$sql = 'DELETE sk ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' sk ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON sk.resource_link_pk = rl.resource_link_pk ' .'WHERE rl.context_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any users in resource links for this context$sql = 'DELETE u ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' u ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON u.resource_link_pk = rl.resource_link_pk ' .'WHERE rl.context_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Update any resource links for which this consumer is acting as a primary resource link$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' prl ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ON prl.primary_resource_link_pk = rl.resource_link_pk ' .'SET prl.primary_resource_link_pk = null, prl.share_approved = null ' .'WHERE rl.context_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete any resource links for this consumer$sql = 'DELETE rl ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' rl ' .'WHERE rl.context_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->execute();// Delete context$sql = 'DELETE c ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::CONTEXT_TABLE_NAME . ' c ' .'WHERE c.context_pk = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$ok = $query->execute();if ($ok) {$context->initialize();}return $ok;}###### ResourceLink methods###/*** Load resource link object.** @param ResourceLink $resourceLink Resource_Link object** @return boolean True if the resource link object was successfully loaded*/public function loadResourceLink($resourceLink){if (!empty($resourceLink->getRecordId())) {$sql = 'SELECT resource_link_pk, context_pk, consumer_pk, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .'WHERE (resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $resourceLink->getRecordId(), PDO::PARAM_INT);} else if (!empty($resourceLink->getContext())) {$sql = 'SELECT resource_link_pk, context_pk, consumer_pk, lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .'WHERE (context_pk = :id) AND (lti_resource_link_id = :rlid)';$query = $this->db->prepare($sql);$query->bindValue('id', $resourceLink->getContext()->getRecordId(), PDO::PARAM_INT);$query->bindValue('rlid', $resourceLink->getId(), PDO::PARAM_STR);} else {$sql = '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 ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' r LEFT OUTER JOIN ' .$this->dbTableNamePrefix . DataConnector::CONTEXT_TABLE_NAME . ' c ON r.context_pk = c.context_pk ' .' WHERE ((r.consumer_pk = :id1) OR (c.consumer_pk = :id2)) AND (lti_resource_link_id = :rlid)';$query = $this->db->prepare($sql);$query->bindValue('id1', $resourceLink->getConsumer()->getRecordId(), PDO::PARAM_INT);$query->bindValue('id2', $resourceLink->getConsumer()->getRecordId(), PDO::PARAM_INT);$query->bindValue('rlid', $resourceLink->getId(), PDO::PARAM_STR);}$ok = $query->execute();if ($ok) {$row = $query->fetch(PDO::FETCH_ASSOC);$ok = ($row !== FALSE);}if ($ok) {$row = array_change_key_case($row);$resourceLink->setRecordId(intval($row['resource_link_pk']));if (!is_null($row['context_pk'])) {$resourceLink->setContextId(intval($row['context_pk']));} else {$resourceLink->setContextId(null);}if (!is_null($row['consumer_pk'])) {$resourceLink->setConsumerId(intval($row['consumer_pk']));} else {$resourceLink->setConsumerId(null);}$resourceLink->ltiResourceLinkId = $row['lti_resource_link_id'];$settings = unserialize($row['settings']);if (!is_array($settings)) {$settings = array();}$resourceLink->setSettings($settings);if (!is_null($row['primary_resource_link_pk'])) {$resourceLink->primaryResourceLinkId = intval($row['primary_resource_link_pk']);} else {$resourceLink->primaryResourceLinkId = null;}$resourceLink->shareApproved = (is_null($row['share_approved'])) ? null : (intval($row['share_approved']) === 1);$resourceLink->created = strtotime($row['created']);$resourceLink->updated = strtotime($row['updated']);}return $ok;}/*** 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) {$time = time();$now = date("{$this->dateFormat} {$this->timeFormat}", $time);$settingsValue = serialize($resourceLink->getSettings());if (!empty($resourceLink->getContext())) {$consumerId = null;$contextId = strval($resourceLink->getContext()->getRecordId());} else if (!empty($resourceLink->getContextId())) {$consumerId = null;$contextId = strval($resourceLink->getContextId());} else {$consumerId = strval($resourceLink->getConsumer()->getRecordId());$contextId = null;}if (empty($resourceLink->primaryResourceLinkId)) {$primaryResourceLinkId = null;} else {$primaryResourceLinkId = $resourceLink->primaryResourceLinkId;}$id = $resourceLink->getRecordId();if (empty($id)) {$sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' (consumer_pk, context_pk, ' .'lti_resource_link_id, settings, primary_resource_link_pk, share_approved, created, updated) ' .'VALUES (:cid, :ctx, :rlid, :settings, :prlid, :share_approved, :created, :updated)';$query = $this->db->prepare($sql);$query->bindValue('cid', $consumerId, PDO::PARAM_INT);$query->bindValue('ctx', $contextId, PDO::PARAM_INT);$query->bindValue('rlid', $resourceLink->getId(), PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('prlid', $primaryResourceLinkId, PDO::PARAM_INT);$query->bindValue('share_approved', $resourceLink->shareApproved, PDO::PARAM_INT);$query->bindValue('created', $now, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);} else if (!is_null($contextId)) {$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' SET ' .'consumer_pk = NULL, context_pk = :ctx, lti_resource_link_id = :rlid, settings = :settings, '.'primary_resource_link_pk = :prlid, share_approved = :share_approved, updated = :updated ' .'WHERE (resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('ctx', $contextId, PDO::PARAM_INT);$query->bindValue('rlid', $resourceLink->getId(), PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('prlid', $primaryResourceLinkId, PDO::PARAM_INT);$query->bindValue('share_approved', $resourceLink->shareApproved, PDO::PARAM_INT);$query->bindValue('updated', $now, PDO::PARAM_STR);$query->bindValue('id', $id, PDO::PARAM_INT);} else {$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' SET ' .'context_pk = :ctx, lti_resource_link_id = :rlid, settings = :settings, '.'primary_resource_link_pk = :prlid, share_approved = :share_approved, updated = :updated ' .'WHERE (consumer_pk = :cid) AND (resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('ctx', $contextId, PDO::PARAM_INT);$query->bindValue('rlid', $resourceLink->getId(), PDO::PARAM_STR);$query->bindValue('settings', $settingsValue, PDO::PARAM_STR);$query->bindValue('prlid', $primaryResourceLinkId, PDO::PARAM_INT);$query->bindValue('share_approved', $resourceLink->shareApproved, PDO::PARAM_INT);$query->bindValue('updated', $now, PDO::PARAM_STR);$query->bindValue('cid', $consumerId, PDO::PARAM_INT);$query->bindValue('id', $id, PDO::PARAM_INT);}$ok = $query->execute();if ($ok) {if (empty($id)) {$resourceLink->setRecordId(intval($this->db->lastInsertId()));$resourceLink->created = $time;}$resourceLink->updated = $time;}return $ok;}/*** Delete resource link object.** @param ResourceLink $resourceLink Resource_Link object** @return boolean True if the resource link object was successfully deleted*/public function deleteResourceLink($resourceLink){$id = $resourceLink->getRecordId();// Delete any outstanding share keys for resource links for this consumer$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .'WHERE (resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$ok = $query->execute();// Delete usersif ($ok) {$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' .'WHERE (resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$ok = $query->execute();}// Update any resource links for which this is the primary resource linkif ($ok) {$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .'SET primary_resource_link_pk = NULL ' .'WHERE (primary_resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$ok = $query->execute();}// Delete resource linkif ($ok) {$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .'WHERE (resource_link_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$ok = $query->execute();}if ($ok) {$resourceLink->initialize();}return $ok;}/*** 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){$id = $resourceLink->getRecordId();$users = array();if ($localOnly) {$sql = 'SELECT u.user_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' AS u ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .'ON u.resource_link_pk = rl.resource_link_pk ' .'WHERE (rl.resource_link_pk = :id) AND (rl.primary_resource_link_pk IS NULL)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);} else {$sql = 'SELECT u.user_pk, u.lti_result_sourcedid, u.lti_user_id, u.created, u.updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' AS u ' ."INNER JOIN {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' AS rl ' .'ON u.resource_link_pk = rl.resource_link_pk ' .'WHERE ((rl.resource_link_pk = :id) AND (rl.primary_resource_link_pk IS NULL)) OR ' .'((rl.primary_resource_link_pk = :pid) AND (share_approved = 1))';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->bindValue('pid', $id, PDO::PARAM_INT);}if ($query->execute()) {while ($row = $query->fetch(PDO::FETCH_ASSOC)) {$row = array_change_key_case($row);$user = ToolProvider\User::fromRecordId($row['user_pk'], $resourceLink->getDataConnector());if (is_null($idScope)) {$users[] = $user;} else {$users[$user->getId($idScope)] = $user;}}}return $users;}/*** Get array of shares defined for this resource link.** @param ResourceLink $resourceLink Resource_Link object** @return array Array of ResourceLinkShare objects*/public function getSharesResourceLink($resourceLink){$id = $resourceLink->getRecordId();$shares = array();$sql = 'SELECT consumer_pk, resource_link_pk, share_approved ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' .'WHERE (primary_resource_link_pk = :id) ' .'ORDER BY consumer_pk';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);if ($query->execute()) {while ($row = $query->fetch(PDO::FETCH_ASSOC)) {$row = array_change_key_case($row);$share = new ToolProvider\ResourceLinkShare();$share->resourceLinkId = intval($row['resource_link_pk']);$share->approved = (intval($row['share_approved']) === 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){$ok = true;// Delete any expired nonce values$now = date("{$this->dateFormat} {$this->timeFormat}", time());$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . ' WHERE expires <= :now';$query = $this->db->prepare($sql);$query->bindValue('now', $now, PDO::PARAM_STR);$query->execute();// Load the nonce$id = $nonce->getConsumer()->getRecordId();$value = $nonce->getValue();$sql = "SELECT value T FROM {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . ' WHERE (consumer_pk = :id) AND (value = :value)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->bindValue('value', $value, PDO::PARAM_STR);$ok = $query->execute();if ($ok) {$row = $query->fetch(PDO::FETCH_ASSOC);if ($row === false) {$ok = false;}}return $ok;}/*** Save nonce object.** @param ConsumerNonce $nonce Nonce object** @return boolean True if the nonce object was successfully saved*/public function saveConsumerNonce($nonce){$id = $nonce->getConsumer()->getRecordId();$value = $nonce->getValue();$expires = date("{$this->dateFormat} {$this->timeFormat}", $nonce->expires);$sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::NONCE_TABLE_NAME . ' (consumer_pk, value, expires) VALUES (:id, :value, :expires)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->bindValue('value', $value, PDO::PARAM_STR);$query->bindValue('expires', $expires, PDO::PARAM_STR);$ok = $query->execute();return $ok;}###### ResourceLinkShareKey methods###/*** Load 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 loaded*/public function loadResourceLinkShareKey($shareKey){$ok = false;// Clear expired share keys$now = date("{$this->dateFormat} {$this->timeFormat}", time());$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' WHERE expires <= :now';$query = $this->db->prepare($sql);$query->bindValue('now', $now, PDO::PARAM_STR);$query->execute();// Load share key$id = $shareKey->getId();$sql = 'SELECT resource_link_pk, auto_approve, expires ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .'WHERE share_key_id = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_STR);if ($query->execute()) {$row = $query->fetch(PDO::FETCH_ASSOC);if ($row !== FALSE) {$row = array_change_key_case($row);if (intval($row['resource_link_pk']) === $shareKey->resourceLinkId) {$shareKey->autoApprove = ($row['auto_approve'] === 1);$shareKey->expires = strtotime($row['expires']);$ok = true;}}}return $ok;}/*** 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){$id = $shareKey->getId();$expires = date("{$this->dateFormat} {$this->timeFormat}", $shareKey->expires);$sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' ' .'(share_key_id, resource_link_pk, auto_approve, expires) ' .'VALUES (:id, :prlid, :approve, :expires)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_STR);$query->bindValue('prlid', $shareKey->resourceLinkId, PDO::PARAM_INT);$query->bindValue('approve', $shareKey->autoApprove, PDO::PARAM_INT);$query->bindValue('expires', $expires, PDO::PARAM_STR);$ok = $query->execute();return $ok;}/*** 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){$id = $shareKey->getId();$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::RESOURCE_LINK_SHARE_KEY_TABLE_NAME . ' WHERE share_key_id = :id';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_STR);$ok = $query->execute();if ($ok) {$shareKey->initialize();}return $ok;}###### User methods###/*** Load user object.** @param User $user User object** @return boolean True if the user object was successfully loaded*/public function loadUser($user){$ok = false;if (!empty($user->getRecordId())) {$id = $user->getRecordId();$sql = 'SELECT user_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' .'WHERE (user_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);} else {$id = $user->getResourceLink()->getRecordId();$uid = $user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY);$sql = 'SELECT user_pk, resource_link_pk, lti_user_id, lti_result_sourcedid, created, updated ' ."FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' .'WHERE (resource_link_pk = :id) AND (lti_user_id = :uid)';$query = $this->db->prepare($sql);$query->bindValue('id', $id, PDO::PARAM_INT);$query->bindValue('uid', $uid, PDO::PARAM_STR);}if ($query->execute()) {$row = $query->fetch(PDO::FETCH_ASSOC);if ($row !== false) {$row = array_change_key_case($row);$user->setRecordId(intval($row['user_pk']));$user->setResourceLinkId(intval($row['resource_link_pk']));$user->ltiUserId = $row['lti_user_id'];$user->ltiResultSourcedId = $row['lti_result_sourcedid'];$user->created = strtotime($row['created']);$user->updated = strtotime($row['updated']);$ok = true;}}return $ok;}/*** Save user object.** @param User $user User object** @return boolean True if the user object was successfully saved*/public function saveUser($user){$time = time();$now = date("{$this->dateFormat} {$this->timeFormat}", $time);if (is_null($user->created)) {$sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' (resource_link_pk, ' .'lti_user_id, lti_result_sourcedid, created, updated) ' .'VALUES (:rlid, :uid, :sourcedid, :created, :updated)';$query = $this->db->prepare($sql);$query->bindValue('rlid', $user->getResourceLink()->getRecordId(), PDO::PARAM_INT);$query->bindValue('uid', $user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY), PDO::PARAM_STR);$query->bindValue('sourcedid', $user->ltiResultSourcedId, PDO::PARAM_STR);$query->bindValue('created', $now, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);} else {$sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' .'SET lti_result_sourcedid = :sourcedid, updated = :updated ' .'WHERE (user_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('sourcedid', $user->ltiResultSourcedId, PDO::PARAM_STR);$query->bindValue('updated', $now, PDO::PARAM_STR);$query->bindValue('id', $user->getRecordId(), PDO::PARAM_INT);}$ok = $query->execute();if ($ok) {if (is_null($user->created)) {$user->setRecordId(intval($this->db->lastInsertId()));$user->created = $time;}$user->updated = $time;}return $ok;}/*** Delete user object.** @param User $user User object** @return boolean True if the user object was successfully deleted*/public function deleteUser($user){$sql = "DELETE FROM {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' .'WHERE (user_pk = :id)';$query = $this->db->prepare($sql);$query->bindValue('id', $user->getRecordId(), PDO::PARAM_INT);$ok = $query->execute();if ($ok) {$user->initialize();}return $ok;}}