├── README.md ├── composer.json ├── example ├── callback.php ├── createfolder.php ├── download.php ├── footer.inc.php ├── header.inc.php ├── index.php ├── logout.php ├── properties.php ├── statics │ ├── audio-icon.png │ ├── file-icon.png │ ├── folder-icon.png │ ├── key-icon.png │ ├── photo-icon.png │ └── video-icon.png ├── tokens └── upload.php └── src └── functions.inc.php /README.md: -------------------------------------------------------------------------------- 1 | php-skydrive 2 | ============ 3 | 4 | A PHP client library for Microsoft SkyDrive/OneDrive. 5 | This is very much a work in progress! 6 | See the Wiki for updates and documentation! 7 | 8 | Update 19-May-2014 - Composer. 9 | - By request, I've created a composer.json and published "lovattj/php-skydrive": "v1.0" on Packagist. 10 | - I've also added an autoloader definition. 11 | - I've not got much Composer or autoloading experience, so if it doesn't work please let me know! 12 | 13 | Update 18-May-2014 - IMPORTANT CHANGE. 14 | - `get_folder` now returns a multidimensional array. 15 | - `$array['data']` is now the array of files. 16 | - `$array['paging']` is an array of page tokens used for pagination. 17 | - Previous behavior was that `$array` on it's own was the array of files only. 18 | - Please update code accordingly and see the Wiki or example project for more information. 19 | 20 | Update 19-Feb-2014: 21 | - Yes! It works with OneDrive fine (new name for SkyDrive). 22 | - Added support for refresh tokens. 23 | - You can now build apps that don't require re-authentication every 60 minutes. 24 | - Also implemented functions to help you build a token store, to help you store tokens if you want to. 25 | - See the Wiki for more information - there are some major changes. 26 | 27 | Update 1-Nov-2013: 28 | - Converted into a Class 29 | - First, edit `functions.inc.php` and include your Live Client ID, Secret Key and oAuth callback URL. 30 | - Call `skydrive_auth::build_oauth_url();` to obtain an oAuth URL. 31 | - Redirect your user to that URL, then call `skydrive_auth::get_oauth_token($_GET['code']);` on the callback to obtain an access token. 32 | - Once you have an access token, create a new object - `$sd = new skydrive($access_token);`. 33 | - Then call the specified method - `$response = $sd->get_folder();` 34 | - Exceptions will be thrown when a non-200 HTTP status code is encountered. 35 | - I'll update the Wiki with new class documentation. Thanks! 36 | 37 | System Requirements: 38 | - PHP 5 (I tested with 5.3.3) 39 | - cURL extension for PHP 40 | 41 | How to install manually: 42 | - Clone project 43 | - Edit "src/functions.inc.php" and include your Live Client ID, Secret Key and oAuth callback URL in relevant places. 44 | - Require "src/functions.inc.php", create an object and start calling functions! 45 | 46 | How to install via Composer: 47 | - Require "lovattj/php-skydrive": "v1.0" in your composer.json 48 | - Edit "vendor/lovattj/php-skydrive/src/functions.inc.php" and include your Live Client ID, Secret Key and oAuth callback URL in relevant places. 49 | - Require "vendor/lovattj/php-skydrive/src/functions.inc.php", create an object and start calling functions! 50 | 51 | How to get the example running: 52 | - Deploy to your web server 53 | - Make sure the file "example/tokens" is read+writable by your web user. 54 | - Edit "src/functions.inc.php" and include your Live Client ID, Secret Key and oAuth callback URL in relevant places. 55 | - Hit "example/index.php" and follow the prompts to login with SkyDrive! 56 | 57 | Questions/Comments: 58 | - E-Mail me at php-skydrive@jlls.info 59 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lovattj/php-skydrive", 3 | "description": "A PHP client library for Microsoft SkyDrive/OneDrive", 4 | "type": "library", 5 | "keywords": ["api","skydrive","onedrive","microsoft","php","client"], 6 | "homepage": "https://github.com/lovattj/php-onedrive", 7 | "license": "GPL", 8 | "authors": [ 9 | { 10 | "name": "Jonathan Lovatt", 11 | "email": "php-skydrive@jlls.info", 12 | "homepage": "http://jlls.info", 13 | "role": "Developer" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=5.3.0" 18 | }, 19 | "autoload": { 20 | "classmap": ["src/"] 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /example/callback.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/createfolder.php: -------------------------------------------------------------------------------- 1 | "; 10 | echo " "; 11 | echo "Login with SkyDrive"; 12 | echo ""; 13 | 14 | } else { 15 | 16 | if (empty($_POST['foldername'])) { 17 | echo 'Error - no new folder name specified'; 18 | } else { 19 | $sd = new skydrive($token); 20 | try { 21 | if (empty($_POST['currentfolderid'])) { 22 | $response = $sd->create_folder(null, $_POST['foldername'], 'Description'); 23 | } else { 24 | $response = $sd->create_folder($_POST['currentfolderid'], $_POST['foldername'], 'Description'); 25 | } 26 | // Folder was created, return metadata. 27 | print_r($response); 28 | } catch (Exception $e) { 29 | // An error occured, print HTTP status code and description. 30 | echo "Error: ".$e->getMessage(); 31 | exit; 32 | } 33 | } 34 | 35 | 36 | } 37 | require_once "footer.inc.php"; 38 | ?> -------------------------------------------------------------------------------- /example/download.php: -------------------------------------------------------------------------------- 1 | download($_GET['fileid']); 11 | ob_end_clean(); 12 | header('Content-Type: application/octet-stream'); 13 | header('Content-Length: '.$response[0]['properties']['size']); 14 | header('Content-Description: File Transfer'); 15 | header('Content-Disposition: attachment; filename='.$response[0]['properties']['name']); 16 | $stdout = fopen('php://output', 'r+'); 17 | fwrite($stdout, $response[0]['data']); 18 | } catch (Exception $e) { 19 | // An error occured, print HTTP status code and description. 20 | echo "Error: ".$e->getMessage(); 21 | exit; 22 | } 23 | } 24 | require_once "footer.inc.php"; 25 | ?> -------------------------------------------------------------------------------- /example/footer.inc.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /example/header.inc.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | php-skydrive demo 9 | 31 | 32 | 33 |
34 |
 php-skydrive demo
35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /example/index.php: -------------------------------------------------------------------------------- 1 | "; 17 | echo " "; 18 | echo "Login with SkyDrive"; 19 | echo ""; 20 | 21 | } else { // Otherwise, if we have a token, use it to create an object and start calling methods to build our page. 22 | 23 | $sd2 = new skydrive($token); 24 | $quotaresp = $sd2->get_quota(); 25 | 26 | echo "Quota remaining: ".round((((int)$quotaresp['available']/1024)/1024))." Mbytes.

"; 27 | echo "

Create folder here:
"; 28 | echo "

 "; 29 | echo "

"; 30 | 31 | // First, time to create a new OneDrive object. 32 | 33 | $sd = new skydrive($token); 34 | 35 | // Time to prepare and make the request to get the list of files. 36 | 37 | if (empty($_GET['folderid'])) { 38 | 39 | if (empty($_GET['offset'])) { 40 | $response = $sd->get_folder(null, 'name', 'ascending', 10); // Gets the first 10 items of the root folder. 41 | } else { 42 | $response = $sd->get_folder(null, 'name', 'ascending', 10, $_GET['offset']); // Gets the next 10 items of the root folder from the specified offset. 43 | } 44 | 45 | $properties = $sd->get_folder_properties(null); 46 | 47 | } else { 48 | 49 | if (empty($_GET['offset'])) { 50 | $response = $sd->get_folder($_GET['folderid'], 'name', 'ascending', 10); // Gets the first 10 items of the specified folder. 51 | } else { 52 | $response = $sd->get_folder($_GET['folderid'], 'name', 'ascending', 10, $_GET['offset']); // Gets the next 10 items of the specified folder from the specified offset. 53 | } 54 | 55 | $properties = $sd->get_folder_properties($_GET['folderid']); 56 | } 57 | 58 | // Now we've got our files and folder properties, time to display them. 59 | 60 | echo "

".$properties['name']."
"; 61 | if (! empty($properties['parent_id'])) { 62 | echo "Up to parent folder"; 63 | } 64 | echo "
"; 65 | echo "
"; 66 | 67 | foreach ($response['data'] as $item) { // Loop through the items in the folder and generate the list of items. 68 | echo "
"; 69 | if ($item['type'] == 'folder' || $item['type'] =='album') { 70 | echo " "; 71 | echo "".$item['name'].""; 72 | } else { 73 | echo " "; 74 | echo "".$item['name']."
"; 75 | echo "Properties
"; 76 | } 77 | echo "
"; 78 | echo "
"; 79 | } 80 | 81 | if (@$response['paging']['nextoffset'] != 0) { 82 | echo "See More"; 83 | } else { 84 | echo "No more files in folder"; 85 | } 86 | echo "
"; 87 | echo "Log Out"; 88 | 89 | } 90 | require_once "footer.inc.php"; 91 | ?> -------------------------------------------------------------------------------- /example/logout.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/properties.php: -------------------------------------------------------------------------------- 1 | "; 9 | echo " "; 10 | echo "Login with SkyDrive"; 11 | echo ""; 12 | } else { 13 | 14 | $sd = new skydrive($token); 15 | try { 16 | $response = $sd->get_file_properties($_GET['fileid']); 17 | echo "

".$response['name']."

"; 18 | echo "Size: ".round(($response['size']/1024),2)."Kb
"; 19 | echo "Created: ".$response['created_time']."
"; 20 | echo "Pre-Signed URL: Copy Link
"; 21 | echo "Permalink: Copy Link

"; 22 | echo "
 Back to containing folder
"; 23 | } catch (Exception $e) { 24 | $errc = ($e->getMessage()); 25 | echo "Error: "; 26 | switch (substr($errc,-3)) { 27 | case "403": 28 | echo "Unauthorised"; 29 | break; 30 | 31 | case "404": 32 | echo "Not found"; 33 | break; 34 | 35 | default: 36 | echo substr($errc,-3); 37 | break; 38 | } 39 | 40 | } 41 | 42 | } 43 | require_once "footer.inc.php"; 44 | ?> -------------------------------------------------------------------------------- /example/statics/audio-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovattj/php-skydrive/19ef73eedc016dab18abe84f5bacf6784f451438/example/statics/audio-icon.png -------------------------------------------------------------------------------- /example/statics/file-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovattj/php-skydrive/19ef73eedc016dab18abe84f5bacf6784f451438/example/statics/file-icon.png -------------------------------------------------------------------------------- /example/statics/folder-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovattj/php-skydrive/19ef73eedc016dab18abe84f5bacf6784f451438/example/statics/folder-icon.png -------------------------------------------------------------------------------- /example/statics/key-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovattj/php-skydrive/19ef73eedc016dab18abe84f5bacf6784f451438/example/statics/key-icon.png -------------------------------------------------------------------------------- /example/statics/photo-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovattj/php-skydrive/19ef73eedc016dab18abe84f5bacf6784f451438/example/statics/photo-icon.png -------------------------------------------------------------------------------- /example/statics/video-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovattj/php-skydrive/19ef73eedc016dab18abe84f5bacf6784f451438/example/statics/video-icon.png -------------------------------------------------------------------------------- /example/tokens: -------------------------------------------------------------------------------- 1 | loggedout -------------------------------------------------------------------------------- /example/upload.php: -------------------------------------------------------------------------------- 1 | "; 9 | echo " "; 10 | echo "Login with SkyDrive"; 11 | echo ""; 12 | 13 | } else { 14 | 15 | $sd = new skydrive($token); 16 | try { 17 | $response = $sd->put_file($_GET['folderid'], '/file/to/put'); 18 | // File was uploaded, return metadata. 19 | print_r($response); 20 | } catch (Exception $e) { 21 | // An error occured, print HTTP status code and description. 22 | echo "Error: ".$e->getMessage(); 23 | exit; 24 | } 25 | 26 | } 27 | require_once "footer.inc.php"; 28 | ?> -------------------------------------------------------------------------------- /src/functions.inc.php: -------------------------------------------------------------------------------- 1 | . 19 | **********************************************************/ 20 | 21 | // Define security credentials for your app. 22 | // You can get these when you register your app on the Live Connect Developer Center. 23 | 24 | define("client_id", "YOUR LIVE CLIENT ID"); 25 | define("client_secret", "YOUR LIVE CLIENT SECRET"); 26 | define("callback_uri", "YOUR CALLBACK URL"); 27 | define("skydrive_base_url", "https://apis.live.net/v5.0/"); 28 | define("token_store", "tokens"); // Edit path to your token store if required, see Wiki for more info. 29 | 30 | class skydrive { 31 | 32 | public $access_token = ''; 33 | 34 | public function __construct($passed_access_token) { 35 | $this->access_token = $passed_access_token; 36 | } 37 | 38 | 39 | // Gets the contents of a SkyDrive folder. 40 | // Pass in the ID of the folder you want to get. 41 | // Or leave the second parameter blank for the root directory (/me/skydrive/files) 42 | // Returns an array of the contents of the folder. 43 | 44 | public function get_folder($folderid, $sort_by='name', $sort_order='ascending', $limit='255', $offset='0') { 45 | if ($folderid === null) { 46 | $response = $this->curl_get(skydrive_base_url."me/skydrive/files?sort_by=".$sort_by."&sort_order=".$sort_order."&offset=".$offset."&limit=".$limit."&access_token=".$this->access_token); 47 | } else { 48 | $response = $this->curl_get(skydrive_base_url.$folderid."/files?sort_by=".$sort_by."&sort_order=".$sort_order."&offset=".$offset."&limit=".$limit."&access_token=".$this->access_token); 49 | } 50 | if (@array_key_exists('error', $response)) { 51 | throw new Exception($response['error']." - ".$response['description']); 52 | exit; 53 | } else { 54 | $arraytoreturn = Array(); 55 | $temparray = Array(); 56 | if (@$response['paging']['next']) { 57 | parse_str($response['paging']['next'], $parseout); 58 | $numerical = array_values($parseout); 59 | } 60 | if (@$response['paging']['previous']) { 61 | parse_str($response['paging']['previous'], $parseout1); 62 | $numerical1 = array_values($parseout1); 63 | } 64 | foreach ($response as $subarray) { 65 | foreach ($subarray as $item) { 66 | if (@array_key_exists('id', $item)) { 67 | array_push($temparray, Array('name' => $item['name'], 'id' => $item['id'], 'type' => $item['type'], 'size' => $item['size'], 'source' => @$item['source'])); 68 | } 69 | } 70 | } 71 | $arraytoreturn['data'] = $temparray; 72 | if (@$numerical[0]) { 73 | if (@$numerical1[0]) { 74 | $arraytoreturn['paging'] = Array('previousoffset' => $numerical1[0], 'nextoffset' => $numerical[0]); 75 | } else { 76 | $arraytoreturn['paging'] = Array('previousoffset' => 0, 'nextoffset' => $numerical[0]); 77 | } 78 | } else { 79 | $arraytoreturn['paging'] = Array('previousoffset' => 0, 'nextoffset' => 0); 80 | } 81 | return $arraytoreturn; 82 | } 83 | } 84 | 85 | // Gets the remaining quota of your SkyDrive account. 86 | // Returns an array containing your total quota and quota available in bytes. 87 | 88 | function get_quota() { 89 | $response = $this->curl_get(skydrive_base_url."me/skydrive/quota?access_token=".$this->access_token); 90 | if (@array_key_exists('error', $response)) { 91 | throw new Exception($response['error']." - ".$response['description']); 92 | exit; 93 | } else { 94 | return $response; 95 | } 96 | } 97 | 98 | // Gets the properties of the folder. 99 | // Returns an array of folder properties. 100 | // You can pass null as $folderid to get the properties of your root SkyDrive folder. 101 | 102 | public function get_folder_properties($folderid) { 103 | $arraytoreturn = Array(); 104 | if ($folderid === null) { 105 | $response = $this->curl_get(skydrive_base_url."/me/skydrive?access_token=".$this->access_token); 106 | } else { 107 | $response = $this->curl_get(skydrive_base_url.$folderid."?access_token=".$this->access_token); 108 | } 109 | 110 | if (@array_key_exists('error', $response)) { 111 | throw new Exception($response['error']." - ".$response['description']); 112 | exit; 113 | } else { 114 | @$arraytoreturn = Array('id' => $response['id'], 'name' => $response['name'], 'parent_id' => $response['parent_id'], 'size' => $response['size'], 'source' => $response['source'], 'created_time' => $response['created_time'], 'updated_time' => $response['updated_time'], 'link' => $response['link'], 'upload_location' => $response['upload_location'], 'is_embeddable' => $response['is_embeddable'], 'count' => $response['count']); 115 | return $arraytoreturn; 116 | } 117 | } 118 | 119 | // Gets the properties of the file. 120 | // Returns an array of file properties. 121 | 122 | public function get_file_properties($fileid) { 123 | $response = $this->curl_get(skydrive_base_url.$fileid."?access_token=".$this->access_token); 124 | if (@array_key_exists('error', $response)) { 125 | throw new Exception($response['error']." - ".$response['description']); 126 | exit; 127 | } else { 128 | $arraytoreturn = Array('id' => $response['id'], 'type' => $response['type'], 'name' => $response['name'], 'parent_id' => $response['parent_id'], 'size' => $response['size'], 'source' => $response['source'], 'created_time' => $response['created_time'], 'updated_time' => $response['updated_time'], 'link' => $response['link'], 'upload_location' => $response['upload_location'], 'is_embeddable' => $response['is_embeddable']); 129 | return $arraytoreturn; 130 | } 131 | } 132 | 133 | // Gets a pre-signed (public) direct URL to the item 134 | // Pass in a file ID 135 | // Returns a string containing the pre-signed URL. 136 | 137 | public function get_source_link($fileid) { 138 | $response = $this->get_file_properties($fileid); 139 | if (@array_key_exists('error', $response)) { 140 | throw new Exception($response['error']." - ".$response['description']); 141 | exit; 142 | } else { 143 | return $response['source']; 144 | } 145 | } 146 | 147 | 148 | // Gets a shared read link to the item. 149 | // This is different to the 'link' returned from get_file_properties in that it's pre-signed. 150 | // It's also a link to the file inside SkyDrive's interface rather than directly to the file data. 151 | 152 | function get_shared_read_link($fileid) { 153 | $response = curl_get(skydrive_base_url.$fileid."/shared_read_link?access_token=".$this->access_token); 154 | if (@array_key_exists('error', $response)) { 155 | throw new Exception($response['error']." - ".$response['description']); 156 | exit; 157 | } else { 158 | return $response['link']; 159 | } 160 | } 161 | 162 | // Gets a shared edit (read-write) link to the item. 163 | 164 | function get_shared_edit_link($fileid) { 165 | $response = curl_get(skydrive_base_url.$fileid."/shared_edit_link?access_token=".$this->access_token); 166 | if (@array_key_exists('error', $response)) { 167 | throw new Exception($response['error']." - ".$response['description']); 168 | exit; 169 | } else { 170 | return $response['link']; 171 | } 172 | } 173 | 174 | // Deletes an object. 175 | 176 | function delete_object($fileid) { 177 | $response = curl_delete(skydrive_base_url.$fileid."?access_token=".$this->access_token); 178 | if (@array_key_exists('error', $response)) { 179 | throw new Exception($response['error']." - ".$response['description']); 180 | exit; 181 | } else { 182 | return true; 183 | } 184 | } 185 | 186 | // Downloads a file from SkyDrive to the server. 187 | // Pass in a file ID. 188 | // Returns a multidimensional array: 189 | // ['properties'] contains the file metadata and ['data'] contains the raw file data. 190 | 191 | public function download($fileid) { 192 | $props = $this->get_file_properties($fileid); 193 | $response = $this->curl_get(skydrive_base_url.$fileid."/content?access_token=".$this->access_token, "false", "HTTP/1.1 302 Found"); 194 | $arraytoreturn = Array(); 195 | if (@array_key_exists('error', $response)) { 196 | throw new Exception($response['error']." - ".$response['description']); 197 | exit; 198 | } else { 199 | array_push($arraytoreturn, Array('properties' => $props, 'data' => $response)); 200 | return $arraytoreturn; 201 | } 202 | } 203 | 204 | 205 | // Uploads a file from disk. 206 | // Pass the $folderid of the folder you want to send the file to, and the $filename path to the file. 207 | // Also use this function for modifying files, it will overwrite a currently existing file. 208 | 209 | function put_file($folderid, $filename) { 210 | $r2s = skydrive_base_url.$folderid."/files/".basename($filename)."?access_token=".$this->access_token; 211 | $response = $this->curl_put($r2s, $filename); 212 | if (@array_key_exists('error', $response)) { 213 | throw new Exception($response['error']." - ".$response['description']); 214 | exit; 215 | } else { 216 | return $response; 217 | } 218 | 219 | } 220 | 221 | /** 222 | * Upload file directly from remote URL 223 | * 224 | * @param string $sourceUrl - URL of the file 225 | * @param string $folderId - folder you want to send the file to 226 | * @param string $filename - target filename after upload 227 | */ 228 | function put_file_from_url($sourceUrl, $folderId, $filename){ 229 | $r2s = skydrive_base_url.$folderId."/files/".$filename."?access_token=".$this->access_token; 230 | 231 | $chunkSizeBytes = 1 * 1024 * 1024; //1MB 232 | 233 | //download file first to tempfile 234 | $tempFilename = tempnam("/tmp", "UPLOAD"); 235 | $temp = fopen($tempFilename, "w"); 236 | 237 | $handle = @fopen($sourceUrl, "rb"); 238 | if($handle === FALSE){ 239 | throw new Exception("Unable to download file from " . $sourceUrl); 240 | } 241 | 242 | while (!feof($handle)) { 243 | $chunk = fread($handle, $chunkSizeBytes); 244 | fwrite($temp, $chunk); 245 | } 246 | 247 | fclose($handle); 248 | fclose($temp); 249 | 250 | //upload to OneDrive 251 | $response = $this->curl_put($r2s, $tempFilename); 252 | if (@array_key_exists('error', $response)) { 253 | throw new Exception($response['error']." - ".$response['description']); 254 | exit; 255 | } else { 256 | unlink($tempFilename); 257 | return $response; 258 | } 259 | } 260 | 261 | 262 | // Creates a folder. 263 | // Pass $folderid as the containing folder (or 'null' to create the folder under the root). 264 | // Also pass $foldername as the name for the new folder and $description as the description. 265 | // Returns the new folder metadata or throws an exception. 266 | 267 | function create_folder($folderid, $foldername, $description="") { 268 | if ($folderid===null) { 269 | $r2s = skydrive_base_url."me/skydrive"; 270 | } else { 271 | $r2s = skydrive_base_url.$folderid; 272 | } 273 | $arraytosend = array('name' => $foldername, 'description' => $description); 274 | $response = $this->curl_post($r2s, $arraytosend, $this->access_token); 275 | if (@array_key_exists('error', $response)) { 276 | throw new Exception($response['error']." - ".$response['description']); 277 | exit; 278 | } else { 279 | $arraytoreturn = Array(); 280 | array_push($arraytoreturn, Array('name' => $response['name'], 'id' => $response['id'])); 281 | return $arraytoreturn; 282 | } 283 | } 284 | 285 | // *** PROTECTED FUNCTIONS *** 286 | 287 | // Internally used function to make a GET request to SkyDrive. 288 | // Functions can override the default JSON-decoding and return just the plain result. 289 | // They can also override the expected HTTP status code too. 290 | 291 | protected function curl_get($uri, $json_decode_output="true", $expected_status_code="HTTP/1.1 200 OK") { 292 | $output = ""; 293 | $output = @file_get_contents($uri); 294 | if ($http_response_header[0] == $expected_status_code) { 295 | if ($json_decode_output == "true") { 296 | return json_decode($output, true); 297 | } else { 298 | return $output; 299 | } 300 | } else { 301 | return Array('error' => 'HTTP status code not expected - got ', 'description' => substr($http_response_header[0],9,3)); 302 | } 303 | } 304 | 305 | // Internally used function to make a POST request to SkyDrive. 306 | 307 | protected function curl_post($uri, $inputarray, $access_token) { 308 | $trimmed = json_encode($inputarray); 309 | try { 310 | $ch = curl_init(); 311 | curl_setopt($ch, CURLOPT_URL, $uri); 312 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 313 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 314 | 'Content-Type: application/json', 315 | 'Authorization: Bearer '.$access_token, 316 | )); 317 | curl_setopt($ch, CURLOPT_POST, TRUE); 318 | curl_setopt($ch, CURLOPT_POSTFIELDS, $trimmed); 319 | $output = curl_exec($ch); 320 | $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 321 | } catch (Exception $e) { 322 | } 323 | if ($httpcode == "201") { 324 | return json_decode($output, true); 325 | } else { 326 | return array('error' => 'HTTP status code not expected - got ', 'description' => $httpcode); 327 | } 328 | } 329 | 330 | // Internally used function to make a PUT request to SkyDrive. 331 | 332 | protected function curl_put($uri, $fp) { 333 | $output = ""; 334 | try { 335 | $pointer = fopen($fp, 'r+'); 336 | $stat = fstat($pointer); 337 | $pointersize = $stat['size']; 338 | $ch = curl_init($uri); 339 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); 340 | curl_setopt($ch, CURLOPT_PUT, true); 341 | curl_setopt($ch, CURLOPT_INFILE, $pointer); 342 | curl_setopt($ch, CURLOPT_INFILESIZE, (int)$pointersize); 343 | curl_setopt($ch, CURLOPT_HEADER, 0); 344 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 345 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); 346 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 347 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 348 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 349 | curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE); 350 | 351 | //HTTP response code 100 workaround 352 | //see http://www.php.net/manual/en/function.curl-setopt.php#82418 353 | curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); 354 | 355 | $output = curl_exec($ch); 356 | $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 357 | } catch (Exception $e) { 358 | } 359 | if ($httpcode == "200" || $httpcode == "201") { 360 | return json_decode($output, true); 361 | } else { 362 | return array('error' => 'HTTP status code not expected - got ', 'description' => $httpcode); 363 | } 364 | 365 | } 366 | 367 | // Internally used function to make a DELETE request to SkyDrive. 368 | 369 | protected function curl_delete($uri) { 370 | $output = ""; 371 | try { 372 | $ch = curl_init($uri); 373 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); 374 | curl_setopt($ch, CURLOPT_HEADER, 0); 375 | curl_setopt($ch, CURLOPT_TIMEOUT, 4); 376 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); 377 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 378 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 379 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 380 | curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE); 381 | $output = curl_exec($ch); 382 | $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 383 | } catch (Exception $e) { 384 | } 385 | if ($httpcode == "200") { 386 | return json_decode($output, true); 387 | } else { 388 | return array('error' => 'HTTP status code not expected - got ', 'description' => $httpcode); 389 | } 390 | } 391 | 392 | 393 | } 394 | 395 | class skydrive_auth { 396 | 397 | // build_oauth_url() 398 | 399 | // Builds a URL for the user to log in to SkyDrive and get the authorization code, which can then be 400 | // passed onto get_oauth_token to get a valid oAuth token. 401 | 402 | public static function build_oauth_url() { 403 | $response = "https://login.live.com/oauth20_authorize.srf?client_id=".client_id."&scope=wl.signin%20wl.offline_access%20wl.skydrive_update%20wl.basic&response_type=code&redirect_uri=".urlencode(callback_uri); 404 | return $response; 405 | } 406 | 407 | 408 | // get_oauth_token() 409 | 410 | // Obtains an oAuth token 411 | // Pass in the authorization code parameter obtained from the inital callback. 412 | // Returns the oAuth token and an expiry time in seconds from now (usually 3600 but may vary in future). 413 | 414 | public static function get_oauth_token($auth) { 415 | $arraytoreturn = array(); 416 | $output = ""; 417 | try { 418 | $ch = curl_init(); 419 | curl_setopt($ch, CURLOPT_URL, "https://login.live.com/oauth20_token.srf"); 420 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 421 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 422 | 'Content-Type: application/x-www-form-urlencoded', 423 | )); 424 | curl_setopt($ch, CURLOPT_POST, TRUE); 425 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 426 | 427 | $data = "client_id=".client_id."&redirect_uri=".urlencode(callback_uri)."&client_secret=".urlencode(client_secret)."&code=".$auth."&grant_type=authorization_code"; 428 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 429 | $output = curl_exec($ch); 430 | } catch (Exception $e) { 431 | } 432 | 433 | $out2 = json_decode($output, true); 434 | $arraytoreturn = Array('access_token' => $out2['access_token'], 'refresh_token' => $out2['refresh_token'], 'expires_in' => $out2['expires_in']); 435 | return $arraytoreturn; 436 | } 437 | 438 | 439 | // refresh_oauth_token() 440 | 441 | // Attempts to refresh an oAuth token 442 | // Pass in the refresh token obtained from a previous oAuth request. 443 | // Returns the new oAuth token and an expiry time in seconds from now (usually 3600 but may vary in future). 444 | 445 | public static function refresh_oauth_token($refresh) { 446 | $arraytoreturn = array(); 447 | $output = ""; 448 | try { 449 | $ch = curl_init(); 450 | curl_setopt($ch, CURLOPT_URL, "https://login.live.com/oauth20_token.srf"); 451 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 452 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 453 | 'Content-Type: application/x-www-form-urlencoded', 454 | )); 455 | curl_setopt($ch, CURLOPT_POST, TRUE); 456 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 457 | 458 | $data = "client_id=".client_id."&redirect_uri=".urlencode(callback_uri)."&client_secret=".urlencode(client_secret)."&refresh_token=".$refresh."&grant_type=refresh_token"; 459 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 460 | $output = curl_exec($ch); 461 | } catch (Exception $e) { 462 | } 463 | 464 | $out2 = json_decode($output, true); 465 | $arraytoreturn = Array('access_token' => $out2['access_token'], 'refresh_token' => $out2['refresh_token'], 'expires_in' => $out2['expires_in']); 466 | return $arraytoreturn; 467 | } 468 | 469 | } 470 | 471 | class skydrive_tokenstore { 472 | 473 | // acquire_token() 474 | 475 | // Will attempt to grab an access_token from the current token store. 476 | // If there isn't one then return false to indicate user needs sending through oAuth procedure. 477 | // If there is one but it's expired attempt to refresh it, save the new tokens and return an access_token. 478 | // If there is one and it's valid then return an access_token. 479 | 480 | 481 | public static function acquire_token() { 482 | 483 | $response = skydrive_tokenstore::get_tokens_from_store(); 484 | if (empty($response['access_token'])) { // No token at all, needs to go through login flow. Return false to indicate this. 485 | return false; 486 | exit; 487 | } else { 488 | if (time() > (int)$response['access_token_expires']) { // Token needs refreshing. Refresh it and then return the new one. 489 | $refreshed = skydrive_auth::refresh_oauth_token($response['refresh_token']); 490 | if (skydrive_tokenstore::save_tokens_to_store($refreshed)) { 491 | $newtokens = skydrive_tokenstore::get_tokens_from_store(); 492 | return $newtokens['access_token']; 493 | } 494 | exit; 495 | } else { 496 | return $response['access_token']; // Token currently valid. Return it. 497 | exit; 498 | } 499 | } 500 | } 501 | 502 | // get_tokens_from_store() 503 | // save_tokens_to_store() 504 | // destroy_tokens_in_store() 505 | 506 | // These functions provide a gateway to your token store. 507 | // In it's basic form, the tokens are written simply to a file called "tokens" in the current working directory, JSON-encoded. 508 | // You can edit the location of the token store by editing the DEFINE entry on line 28. 509 | 510 | // If you want to implement your own token store, you can edit these functions and implement your own code, e.g. if you want to store them in a database. 511 | // You MUST save and retrieve tokens in such a way that calls to get_tokens_from_store() will return an associative array 512 | // which contains the access token as 'access_token', the refresh token as 'refresh_token' and the expiry (as a UNIX timestamp) as 'access_token_expires' 513 | 514 | // For more information, see the Wiki on GitHub. 515 | 516 | public static function get_tokens_from_store() { 517 | $response = json_decode(file_get_contents(token_store), TRUE); 518 | return $response; 519 | } 520 | 521 | public static function save_tokens_to_store($tokens) { 522 | $tokentosave = Array(); 523 | $tokentosave = Array('access_token' => $tokens['access_token'], 'refresh_token' => $tokens['refresh_token'], 'access_token_expires' => (time()+(int)$tokens['expires_in'])); 524 | if (file_put_contents(token_store, json_encode($tokentosave))) { 525 | return true; 526 | } else { 527 | return false; 528 | } 529 | } 530 | 531 | public static function destroy_tokens_in_store() { 532 | if (file_put_contents(token_store, "loggedout")) { 533 | return true; 534 | } else { 535 | return false; 536 | } 537 | 538 | } 539 | } 540 | 541 | ?> 542 | --------------------------------------------------------------------------------