diff --git a/local/o365/classes/rest/onedrive.php b/local/o365/classes/rest/onedrive.php index ce6db251e..0722ca181 100644 --- a/local/o365/classes/rest/onedrive.php +++ b/local/o365/classes/rest/onedrive.php @@ -79,25 +79,36 @@ public static function get_resource() { * Get the embedding URL for a given file id. * * @param string $fileid The ID of the file (from the odb api). + * @param string $fileurl The o365 webUrl property of the file. * @return string|null The URL to be embedded, or null if error. */ - public function get_embed_url($fileid) { - $fileinfo = $this->get_file_metadata($fileid); - $odburl = $this->get_resource(); - if (isset($fileinfo['webUrl'])) { - if (strpos($fileinfo['webUrl'], $odburl) === 0) { - $filerelative = substr($fileinfo['webUrl'], strlen($odburl)); - + public function get_embed_url($fileid, $fileurl = '') { + if (empty($fileurl)) { + $fileinfo = $this->get_file_metadata($fileid); + if (isset($fileinfo['webUrl'])) { + $fileurl = $fileinfo['webUrl']; } } - $filerelativeparts = explode('/', trim($filerelative, '/')); - $spapiurl = $odburl.'/'.$filerelativeparts[0].'/'.$filerelativeparts[1].'/_api'; - $this->apiurioverride = $spapiurl; - $endpoint = '/web/GetFileByServerRelativeUrl(\''.$filerelative.'\')/ListItemAllFields/GetWOPIFrameUrl(3)'; - $response = $this->apicall('post', $endpoint); - unset($this->apiurioverride); - $response = json_decode($response, true); - return (!empty($response) && isset($response['value'])) ? $response['value'] : null; + if (!empty($fileurl)) { + $odburl = $this->get_resource(); + if (strpos($fileurl, $odburl) === 0) { + $filerelative = substr($fileurl, strlen($odburl)); + $filerelativeparts = explode('/', trim($filerelative, '/')); + $spapiurl = $odburl.'/'.$filerelativeparts[0].'/'.$filerelativeparts[1].'/_api'; + $this->apiurioverride = $spapiurl; + if (substr($filerelative, -6) === '?web=1') { + $filerelative = substr($filerelative, 0, -6); + } + $endpoint = '/web/GetFileByServerRelativeUrl(\''.$filerelative.'\')/ListItemAllFields/GetWOPIFrameUrl(3)'; + $response = $this->apicall('post', $endpoint); + unset($this->apiurioverride); + $response = json_decode($response, true); + if (!empty($response) && isset($response['value'])) { + return $response['value']; + } + } + } + return null; } /** diff --git a/repository/office365/lib.php b/repository/office365/lib.php index 659a97906..8dc37a6c3 100644 --- a/repository/office365/lib.php +++ b/repository/office365/lib.php @@ -35,10 +35,13 @@ class repository_office365 extends \repository { protected $httpclient; /** @var array Array of onedrive status and token information. */ - protected $onedrive = ['configured' => false, 'token' => []]; + protected $onedrive = ['configured' => false]; /** @var array Array of sharepoint status and token information. */ - protected $sharepoint = ['configured' => false, 'token' => []]; + protected $sharepoint = ['configured' => false]; + + /** @var \local_o365\oauth2\clientdata A clientdata object to use with an o365 api class. */ + protected $clientdata = null; /** * Constructor @@ -60,23 +63,33 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a throw new \moodle_exception('errorauthoidcnotconfig', 'repository_office365'); } - $this->onedrive['configured'] = \local_o365\rest\onedrive::is_configured(); - if ($this->onedrive['configured'] === true) { - $onedriveresource = \local_o365\rest\onedrive::get_resource(); - $tokenrec = $DB->get_record('local_o365_token', ['user_id' => $USER->id, 'resource' => $onedriveresource]); - if (!empty($tokenrec)) { - $this->onedrive['token'] = $tokenrec; - } - } + $this->clientdata = new \local_o365\oauth2\clientdata($this->oidcconfig->clientid, $this->oidcconfig->clientsecret, + $this->oidcconfig->authendpoint, $this->oidcconfig->tokenendpoint); + $this->onedrive['configured'] = \local_o365\rest\onedrive::is_configured(); $this->sharepoint['configured'] = \local_o365\rest\sharepoint::is_configured(); - if ($this->sharepoint['configured'] === true) { - $sharepointresource = \local_o365\rest\sharepoint::get_resource(); - $tokenrec = $DB->get_record('local_o365_token', ['user_id' => $USER->id, 'resource' => $sharepointresource]); - if (!empty($tokenrec)) { - $this->sharepoint['token'] = $tokenrec; - } - } + } + + /** + * Get a OneDrive token. + * + * @return \local_o365\oauth2\token A OneDrive token object. + */ + protected function get_onedrive_token() { + global $USER; + $resource = \local_o365\rest\onedrive::get_resource(); + return \local_o365\oauth2\token::instance($USER->id, $resource, $this->clientdata, $this->httpclient); + } + + /** + * Get a SharePoint token. + * + * @return \local_o365\oauth2\token A SharePoint token object. + */ + protected function get_sharepoint_token() { + global $USER; + $resource = \local_o365\rest\sharepoint::get_resource(); + return \local_o365\oauth2\token::instance($USER->id, $resource, $this->clientdata, $this->httpclient); } /** @@ -85,13 +98,11 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a * @return \local_o365\rest\onedrive A onedrive API client object. */ protected function get_onedrive_apiclient() { - if ($this->onedrive['configured'] === true && !empty($this->onedrive['token'])) { - $clientdata = new \local_o365\oauth2\clientdata($this->oidcconfig->clientid, $this->oidcconfig->clientsecret, - $this->oidcconfig->authendpoint, $this->oidcconfig->tokenendpoint); - $token = new \local_o365\oauth2\token($this->onedrive['token']->token, $this->onedrive['token']->expiry, - $this->onedrive['token']->refreshtoken, $this->onedrive['token']->scope, - $this->onedrive['token']->resource, $this->onedrive['token']->user_id, $clientdata, $this->httpclient); - return new \local_o365\rest\onedrive($token, $this->httpclient); + if ($this->onedrive['configured'] === true) { + $token = $this->get_onedrive_token(); + if (!empty($token)) { + return new \local_o365\rest\onedrive($token, $this->httpclient); + } } return false; } @@ -102,14 +113,11 @@ protected function get_onedrive_apiclient() { * @return \local_o365\rest\sharepoint A sharepoint API client object. */ protected function get_sharepoint_apiclient() { - if ($this->sharepoint['configured'] === true && !empty($this->sharepoint['token'])) { - $clientdata = new \local_o365\oauth2\clientdata($this->oidcconfig->clientid, $this->oidcconfig->clientsecret, - $this->oidcconfig->authendpoint, $this->oidcconfig->tokenendpoint); - $token = new \local_o365\oauth2\token($this->sharepoint['token']->token, $this->sharepoint['token']->expiry, - $this->sharepoint['token']->refreshtoken, $this->sharepoint['token']->scope, - $this->sharepoint['token']->resource, $this->sharepoint['token']->user_id, $clientdata, $this->httpclient); - - return new \local_o365\rest\sharepoint($token, $this->httpclient); + if ($this->sharepoint['configured'] === true) { + $token = $this->get_sharepoint_token(); + if (!empty($token)) { + return new \local_o365\rest\sharepoint($token, $this->httpclient); + } } return false; } @@ -160,18 +168,34 @@ public function get_listing($path = '', $page = '') { $list = []; $breadcrumb = [['name' => $this->name, 'path' => '/']]; + $onedriveactive = false; + if ($this->onedrive['configured'] === true) { + $onedrivetoken = $this->get_onedrive_token(); + if (!empty($onedrivetoken)) { + $onedriveactive = true; + } + } + + $sharepointactive = false; + if ($this->sharepoint['configured'] === true) { + $sharepointtoken = $this->get_sharepoint_token(); + if (!empty($sharepointtoken)) { + $sharepointactive = true; + } + } + if (strpos($path, '/my/') === 0) { - if ($this->onedrive['configured'] === true && !empty($this->onedrive['token'])) { + if ($onedriveactive === true) { // Path is in my files. list($list, $breadcrumb) = $this->get_listing_my(substr($path, 3)); } } else if (strpos($path, '/courses/') === 0) { - if ($this->sharepoint['configured'] === true && !empty($this->sharepoint['token'])) { + if ($sharepointactive === true) { // Path is in course files. list($list, $breadcrumb) = $this->get_listing_course(substr($path, 8)); } } else { - if ($this->onedrive['configured'] === true && !empty($this->onedrive['token'])) { + if ($onedriveactive === true) { $list[] = [ 'title' => get_string('myfiles', 'repository_office365'), 'path' => '/my/', @@ -179,7 +203,7 @@ public function get_listing($path = '', $page = '') { 'children' => [], ]; } - if ($this->sharepoint['configured'] === true && !empty($this->sharepoint['token'])) { + if ($sharepointactive === true) { $list[] = [ 'title' => get_string('courses', 'repository_office365'), 'path' => '/courses/', @@ -633,10 +657,14 @@ public function send_file($storedfile, $lifetime=null , $filter=0, $forcedownloa if ($_SERVER['SCRIPT_NAME'] !== '/draftfile.php') { if ($reference['source'] === 'onedrive') { $sourceclient = $this->get_onedrive_apiclient(); - $embedurl = $sourceclient->get_embed_url($reference['id']); + $fileurl = (isset($reference['url'])) ? $reference['url'] : ''; + $embedurl = $sourceclient->get_embed_url($reference['id'], $fileurl); if (!empty($embedurl)) { header('Location: '.$embedurl); die(); + } else if (!empty($fileurl)) { + header('Location: '.$fileurl); + die(); } } }