Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Functions for operating with the skydrive API
  19   *
  20   * @package    repository_skydrive
  21   * @copyright  2012 Lancaster University Network Services Ltd
  22   * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  require_once($CFG->libdir.'/oauthlib.php');
  30  
  31  /**
  32   * A helper class to access microsoft live resources using the api.
  33   *
  34   * This uses the microsfot API defined in
  35   * http://msdn.microsoft.com/en-us/library/hh243648.aspx
  36   *
  37   * @package    repository_skydrive
  38   * @copyright  2012 Lancaster University Network Services Ltd
  39   * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class microsoft_skydrive extends oauth2_client {
  43      /** @var string OAuth 2.0 scope */
  44      const SCOPE = 'wl.skydrive';
  45      /** @var string Base url to access API */
  46      const API = 'https://apis.live.net/v5.0';
  47      /** @var cache_session cache of foldernames */
  48      var $foldernamecache = null;
  49  
  50      /**
  51       * Construct a skydrive request object
  52       *
  53       * @param string $clientid client id for OAuth 2.0 provided by microsoft
  54       * @param string $clientsecret secret for OAuth 2.0 provided by microsoft
  55       * @param moodle_url $returnurl url to return to after succseful auth
  56       */
  57      public function __construct($clientid, $clientsecret, $returnurl) {
  58          parent::__construct($clientid, $clientsecret, $returnurl, self::SCOPE);
  59          // Make a session cache
  60          $this->foldernamecache = cache::make('repository_skydrive', 'foldername');
  61      }
  62  
  63      /**
  64       * Returns the auth url for OAuth 2.0 request
  65       * @return string the auth url
  66       */
  67      protected function auth_url() {
  68          return 'https://login.live.com/oauth20_authorize.srf';
  69      }
  70  
  71      /**
  72       * Returns the token url for OAuth 2.0 request
  73       * @return string the auth url
  74       */
  75      protected function token_url() {
  76          return 'https://login.live.com/oauth20_token.srf';
  77      }
  78  
  79      /**
  80       * Post request.
  81       *
  82       * Overridden to convert the data to a string, else curl will set the wrong headers.
  83       *
  84       * @param string $url The URL.
  85       * @param array|string $params The parameters.
  86       * @param array $options The options.
  87       * @return bool
  88       */
  89      public function post($url, $params = '', $options = array()) {
  90          return parent::post($url, format_postdata_for_curlcall($params), $options);
  91      }
  92  
  93      /**
  94       * Downloads a file to a  file from skydrive using authenticated request
  95       *
  96       * @param string $id id of file
  97       * @param string $path path to save file to
  98       * @return array stucture for repository download_file
  99       */
 100      public function download_file($id, $path) {
 101          $url = self::API."/$id}/content";
 102          // Microsoft live redirects to the real download location..
 103          $this->setopt(array('CURLOPT_FOLLOWLOCATION' => true, 'CURLOPT_MAXREDIRS' => 3));
 104          $content = $this->get($url);
 105          file_put_contents($path, $content);
 106          return array('path'=>$path, 'url'=>$url);
 107      }
 108  
 109      /**
 110       * Returns a folder name property for a given folderid.
 111       *
 112       * @param string $folderid the folder id which is passed
 113       * @return mixed folder name or false in case of error
 114       */
 115      public function get_folder_name($folderid) {
 116          if (empty($folderid)) {
 117              throw new coding_exception('Empty folderid passed to get_folder_name');
 118          }
 119  
 120          // Cache based on oauthtoken and folderid.
 121          $cachekey = $this->folder_cache_key($folderid);
 122  
 123          if ($foldername = $this->foldernamecache->get($cachekey)) {
 124              return $foldername;
 125          }
 126  
 127          $url = self::API."/{$folderid}";
 128          $ret = json_decode($this->get($url));
 129          if (isset($ret->error)) {
 130              $this->log_out();
 131              return false;
 132          }
 133  
 134          $this->foldernamecache->set($cachekey, $ret->name);
 135          return $ret->name;
 136      }
 137  
 138      /**
 139       * Returns a list of files the user has formated for files api
 140       *
 141       * @param string $path the path which we are in
 142       * @return mixed Array of files formated for fileapoi
 143       */
 144      public function get_file_list($path = '') {
 145          global $OUTPUT;
 146  
 147          $precedingpath = '';
 148          if (empty($path)) {
 149              $url = self::API."/me/skydrive/files/";
 150          } else {
 151              $parts = explode('/', $path);
 152              $currentfolder = array_pop($parts);
 153              $url = self::API."/{$currentfolder}/files/";
 154          }
 155  
 156          $ret = json_decode($this->get($url));
 157  
 158          if (isset($ret->error)) {
 159              $this->log_out();
 160              return false;
 161          }
 162  
 163          $files = array();
 164  
 165          foreach ($ret->data as $file) {
 166              switch($file->type) {
 167                  case 'folder':
 168                  case 'album':
 169                      // Cache the foldername for future requests.
 170                      $cachekey = $this->folder_cache_key($file->id);
 171                      $this->foldernamecache->set($cachekey, $file->name);
 172  
 173                      $files[] = array(
 174                          'title' => $file->name,
 175                          'path' => $path.'/'.$file->id,
 176                          'size' => 0,
 177                          'date' => strtotime($file->updated_time),
 178                          'thumbnail' => $OUTPUT->image_url(file_folder_icon(90))->out(false),
 179                          'children' => array(),
 180                      );
 181                      break;
 182                  case 'photo':
 183                      $files[] = array(
 184                          'title' => $file->name,
 185                          'size' => $file->size,
 186                          'date' => strtotime($file->updated_time),
 187                          'thumbnail' => $OUTPUT->image_url(file_extension_icon($file->name, 90))->out(false),
 188                          'realthumbnail' => $file->picture,
 189                          'source' => $file->id,
 190                          'url' => $file->link,
 191                          'image_height' => $file->height,
 192                          'image_width' => $file->width,
 193                          'author' => $file->from->name,
 194                      );
 195                      break;
 196                  case 'video':
 197                      $files[] = array(
 198                          'title' => $file->name,
 199                          'size' => $file->size,
 200                          'date' => strtotime($file->updated_time),
 201                          'thumbnail' => $OUTPUT->image_url(file_extension_icon($file->name, 90))->out(false),
 202                          'realthumbnail' => $file->picture,
 203                          'source' => $file->id,
 204                          'url' => $file->link,
 205                          'author' => $file->from->name,
 206                      );
 207                      break;
 208                  case 'audio':
 209                      $files[] = array(
 210                          'title' => $file->name,
 211                          'size' => $file->size,
 212                          'date' => strtotime($file->updated_time),
 213                          'thumbnail' => $OUTPUT->image_url(file_extension_icon($file->name, 90))->out(false),
 214                          'source' => $file->id,
 215                          'url' => $file->link,
 216                          'author' => $file->from->name,
 217                      );
 218                      break;
 219                  case 'file':
 220                      $files[] = array(
 221                          'title' => $file->name,
 222                          'size' => $file->size,
 223                          'date' => strtotime($file->updated_time),
 224                          'thumbnail' => $OUTPUT->image_url(file_extension_icon($file->name, 90))->out(false),
 225                          'source' => $file->id,
 226                          'url' => $file->link,
 227                          'author' => $file->from->name,
 228                      );
 229                      break;
 230              }
 231          }
 232          return $files;
 233      }
 234  
 235      /**
 236       * Returns a key for foldernane cache
 237       *
 238       * @param string $folderid the folder id which is to be cached
 239       * @return string the cache key to use
 240       */
 241      private function folder_cache_key($folderid) {
 242          // Cache based on oauthtoken and folderid.
 243          return $this->get_tokenname().'_'.$folderid;
 244      }
 245  }