MDL-30740 skydrive: Add filepicker navigation bar
[moodle.git] / repository / skydrive / microsoftliveapi.php
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/>.
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  */
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->libdir.'/oauthlib.php');
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;
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_from_params(cache_store::MODE_SESSION, 'repository_skydrive', 'foldernamelist');
61     }
63     /**
64      * Should HTTP GET be used instead of POST?
65      *
66      * The Microsoft API does not support POST, so we should use
67      * GET instead (with the auth_token passed as a GET param).
68      *
69      * @return bool true if GET should be used
70      */
71     protected function use_http_get() {
72         return true;
73     }
75     /**
76      * Returns the auth url for OAuth 2.0 request
77      * @return string the auth url
78      */
79     protected function auth_url() {
80         return 'https://oauth.live.com/authorize';
81     }
83     /**
84      * Returns the token url for OAuth 2.0 request
85      * @return string the auth url
86      */
87     protected function token_url() {
88         return 'https://oauth.live.com/token';
89     }
91     /**
92      * Downloads a file to a  file from skydrive using authenticated request
93      *
94      * @param string $id id of file
95      * @param string $path path to save file to
96      * @return array stucture for repository download_file
97      */
98     public function download_file($id, $path) {
99         $url = self::API."/${id}/content";
100         // Microsoft live redirects to the real download location..
101         $this->setopt(array('CURLOPT_FOLLOWLOCATION' => true, 'CURLOPT_MAXREDIRS' => 3));
102         $content = $this->get($url);
103         file_put_contents($path, $content);
104         return array('path'=>$path, 'url'=>$url);
105     }
107     /**
108      * Returns a folder name property for a given folderid.
109      *
110      * @param string $folderid the folder id which is passed
111      * @return mixed folder name or false in case of error
112      */
113     public function get_folder_name($folderid) {
114         if (empty($folderid)) {
115             throw new coding_exception('Empty folderid passed to get_folder_name');
116         }
118         // Cache based on oauthtoken and folderid.
119         $cachekey = $this->folder_cache_key($folderid);
121         if ($foldername = $this->foldernamecache->get($cachekey)) {
122             return $foldername;
123         }
125         $url = self::API."/{$folderid}";
126         $ret = json_decode($this->get($url));
127         if (isset($ret->error)) {
128             $this->log_out();
129             return false;
130         }
132         $this->foldernamecache->set($cachekey, $ret->name);
133         return $ret->name;
134     }
136     /**
137      * Returns a list of files the user has formated for files api
138      *
139      * @param string $path the path which we are in
140      * @return mixed Array of files formated for fileapoi
141      */
142     public function get_file_list($path = '') {
143         global $OUTPUT;
145         $precedingpath = '';
146         if (empty($path)) {
147             $url = self::API."/me/skydrive/files/";
148         } else {
149             $parts = explode('/', $path);
150             $currentfolder = array_pop($parts);
151             $url = self::API."/{$currentfolder}/files/";
152         }
154         $ret = json_decode($this->get($url));
156         if (isset($ret->error)) {
157             $this->log_out();
158             return false;
159         }
161         $files = array();
163         foreach ($ret->data as $file) {
164             switch($file->type) {
165                 case 'folder':
166                 case 'album':
167                     // Cache the foldername for future requests.
168                     $cachekey = $this->folder_cache_key($file->id);
169                     $this->foldernamecache->set($cachekey, $file->name);
171                     $files[] = array(
172                         'title' => $file->name,
173                         'path' => $path.'/'.$file->id,
174                         'size' => 0,
175                         'date' => strtotime($file->updated_time),
176                         'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false),
177                         'children' => array(),
178                     );
179                     break;
180                 case 'photo':
181                     $files[] = array(
182                         'title' => $file->name,
183                         'size' => $file->size,
184                         'date' => strtotime($file->updated_time),
185                         'thumbnail' => $file->picture,
186                         'source' => $file->id,
187                         'url' => $file->link,
188                     );
189                     break;
190                 case 'video':
191                     $files[] = array(
192                         'title' => $file->name,
193                         'size' => $file->size,
194                         'date' => strtotime($file->updated_time),
195                         'thumbnail' => $file->picture,
196                         'source' => $file->id,
197                         'url' => $file->link,
198                     );
199                     break;
200                 case 'audio':
201                     $files[] = array(
202                         'title' => $file->name,
203                         'size' => $file->size,
204                         'date' => strtotime($file->updated_time),
205                         'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->name, 90))->out(false),
206                         'source' => $file->id,
207                         'url' => $file->link,
208                     );
209                     break;
210                 case 'file':
211                     $files[] = array(
212                         'title' => $file->name,
213                         'size' => $file->size,
214                         'date' => strtotime($file->updated_time),
215                         'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->name, 90))->out(false),
216                         'source' => $file->id,
217                         'url' => $file->link,
218                     );
219                     break;
220             }
221         }
222         return $files;
223     }
225     /**
226      * Returns a key for foldernane cache
227      *
228      * @param string $folderid the folder id which is to be cached
229      * @return string the cache key to use
230      */
231     private function folder_cache_key($folderid) {
232         // Cache based on oauthtoken and folderid.
233         return $this->get_tokenname().'_'.$folderid;
234     }