PluginProbe
ManageWP Worker / 3.9.20
ManageWP Worker v3.9.20
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / lib / dropbox.oauth.php

dropbox.oauth.php in ManageWP Worker 3.9.20, at lib/dropbox.oauth.php

1,135 lines 33.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Dropbox class
5 *
6 * This source file can be used to communicate with Dropbox (http://dropbox.com)
7 *
8 * The class is documented in the file itself. If you find any bugs help me out and report them. Reporting can be done by sending an email to php-dropbox-bugs[at]verkoyen[dot]eu.
9 * If you report a bug, make sure you give me enough information (include your code).
10 *
11 * Changelog since 1.0.4
12 * - Fixed filesPost so it returns a boolean.
13 * - Some code styling
14 *
15 * Changelog since 1.0.3
16 * - Corrected the authorize-URL (thx to Jacob Budin).
17 *
18 * Changelog since 1.0.2
19 * - Added methods to enable oauth-usage.
20 *
21 * Changelog since 1.0.1
22 * - Bugfix: when doing multiple calles where GET and POST is mixed, the postfields should be reset (thx to Daniel Hトてスsken)
23 *
24 * Changelog since 1.0.0
25 * - fixed some issues with generation off the basestring
26 *
27 * License
28 * Copyright (c), Tijs Verkoyen. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
31 *
32 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
34 * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
35 *
36 * This software is provided by the author "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
37 *
38 * @author Tijs Verkoyen <[email protected]>
39 * @version 1.0.5
40 *
41 * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
42 * @license BSD License
43 */
44 class Dropbox
45 {
46 // internal constant to enable/disable debugging
47 const DEBUG = false;
48
49 // url for the dropbox-api
50 const API_URL = 'https://api.dropbox.com';
51 const API_AUTH_URL = 'https://www.dropbox.com';
52 const API_CONTENT_URL = 'https://api-content.dropbox.com';
53
54 // port for the dropbox-api
55 const API_PORT = 443;
56
57 // current version
58 const VERSION = '1.0.5';
59
60
61 /**
62 * A cURL instance
63 *
64 * @var resource
65 */
66 private $curl;
67
68
69 /**
70 * The application key
71 *
72 * @var string
73 */
74 private $applicationKey;
75
76
77 /**
78 * The application secret
79 *
80 * @var string
81 */
82 private $applicationSecret;
83
84
85 /**
86 * The oAuth-token
87 *
88 * @var string
89 */
90 private $oAuthToken = '';
91
92
93 /**
94 * The oAuth-token-secret
95 *
96 * @var string
97 */
98 private $oAuthTokenSecret = '';
99
100
101 /**
102 * The timeout
103 *
104 * @var int
105 */
106 private $timeOut = 60;
107
108
109 /**
110 * The user agent
111 *
112 * @var string
113 */
114 private $userAgent;
115
116
117 // class methods
118 /**
119 * Default constructor
120 *
121 * @return void
122 * @param string $applicationKey The application key to use.
123 * @param string $applicationSecret The application secret to use.
124 */
125 public function __construct($applicationKey, $applicationSecret)
126 {
127 $this->setApplicationKey($applicationKey);
128 $this->setApplicationSecret($applicationSecret);
129 }
130
131
132 /**
133 * Default destructor
134 *
135 * @return void
136 */
137 public function __destruct()
138 {
139 if($this->curl != null) curl_close($this->curl);
140 }
141
142
143 /**
144 * Format the parameters as a querystring
145 *
146 * @return string
147 * @param array $parameters The parameters to pass.
148 */
149 private function buildQuery(array $parameters)
150 {
151 // no parameters?
152 if(empty($parameters)) return '';
153
154 // encode the keys
155 $keys = self::urlencode_rfc3986(array_keys($parameters));
156
157 // encode the values
158 $values = self::urlencode_rfc3986(array_values($parameters));
159
160 // reset the parameters
161 $parameters = array_combine($keys, $values);
162
163 // sort parameters by key
164 uksort($parameters, 'strcmp');
165
166 // loop parameters
167 foreach($parameters as $key => $value)
168 {
169 // sort by value
170 if(is_array($value)) $parameters[$key] = natsort($value);
171 }
172
173 // process parameters
174 foreach($parameters as $key => $value) $chunks[] = $key . '=' . str_replace('%25', '%', $value);
175
176 // return
177 return implode('&', $chunks);
178 }
179
180
181 /**
182 * All OAuth 1.0 requests use the same basic algorithm for creating a signature base string and a signature.
183 * The signature base string is composed of the HTTP method being used, followed by an ampersand ("&") and then the URL-encoded base URL being accessed,
184 * complete with path (but not query parameters), followed by an ampersand ("&").
185 * Then, you take all query parameters and POST body parameters (when the POST body is of the URL-encoded type, otherwise the POST body is ignored),
186 * including the OAuth parameters necessary for negotiation with the request at hand, and sort them in lexicographical order by first parameter name and
187 * then parameter value (for duplicate parameters), all the while ensuring that both the key and the value for each parameter are URL encoded in isolation.
188 * Instead of using the equals ("=") sign to mark the key/value relationship, you use the URL-encoded form of "%3D". Each parameter is then joined by the
189 * URL-escaped ampersand sign, "%26".
190 *
191 * @return string
192 * @param string $url The url to use.
193 * @param string $method The method that will be called.
194 * @param array $parameters The parameters to pass.
195 */
196 private function calculateBaseString($url, $method, array $parameters)
197 {
198 // redefine
199 $url = (string) $url;
200 $parameters = (array) $parameters;
201
202 // init var
203 $pairs = array();
204 $chunks = array();
205
206 // sort parameters by key
207 uksort($parameters, 'strcmp');
208
209 // loop parameters
210 foreach($parameters as $key => $value)
211 {
212 // sort by value
213 if(is_array($value)) $parameters[$key] = natsort($value);
214 }
215
216 // process queries
217 foreach($parameters as $key => $value)
218 {
219 // only add if not already in the url
220 if(substr_count($url, $key . '=' . $value) == 0) $chunks[] = self::urlencode_rfc3986($key) . '%3D' . self::urlencode_rfc3986($value);
221 }
222
223 $urlChunks = explode('/', $url);
224 $i = 0;
225
226 foreach($urlChunks as &$chunk)
227 {
228 if($i > 4) $chunk = self::urlencode_rfc3986($chunk);
229 else $chunk = urlencode($chunk);
230
231 $i++;
232
233 }
234
235 // build base
236 $base = $method . '&';
237 $base .= implode('%2F', $urlChunks);
238 $base .= (substr_count($url, '?')) ? '%26' : '&';
239 $base .= implode('%26', $chunks);
240 $base = str_replace(array('%3F', '%20'), array('&', '%2520'), $base);
241
242 // return
243 return $base;
244 }
245
246
247 /**
248 * Build the Authorization header
249 * @later: fix me
250 *
251 * @return string
252 * @param array $parameters The parameters to pass.
253 * @param string $url The url to use.
254 */
255 private function calculateHeader(array $parameters, $url)
256 {
257 // redefine
258 $url = (string) $url;
259
260 // divide into parts
261 $parts = parse_url($url);
262
263 // init var
264 $chunks = array();
265
266 // process queries
267 foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', self::urlencode_rfc3986($key) . '="' . self::urlencode_rfc3986($value) . '"');
268 $parts['path']=str_replace("%2F", "/", rawurlencode($parts['path']));
269 // build return
270 $return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
271 $return .= implode(',', $chunks);
272 // prepend name and OAuth part
273 return $return;
274 }
275
276
277 /**
278 * Make an call to the oAuth
279 * @todo refactor me
280 *
281 * @return array
282 * @param string $url The url that has to be called.
283 * @param array[optional] $parameters The parameters to pass.
284 * @param string[optional] $method Which HTTP-method should we use? Possible values are POST, GET.
285 * @param bool[optional] $expectJSON Do we expect JSON?
286 */
287 private function doOAuthCall($url, array $parameters = null, $method = 'POST', $expectJSON = true)
288 {
289 // redefine
290 $url = (string) $url;
291
292 // append default parameters
293 $parameters['oauth_consumer_key'] = $this->getApplicationKey();
294 $parameters['oauth_nonce'] = md5(microtime() . rand());
295 $parameters['oauth_timestamp'] = time();
296 $parameters['oauth_signature_method'] = 'HMAC-SHA1';
297 $parameters['oauth_version'] = '1.0';
298
299 // calculate the base string
300 $base = $this->calculateBaseString(self::API_URL . '/' . $url, 'POST', $parameters);
301
302 // add sign into the parameters
303 $parameters['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base);
304
305 // calculate header
306 $header = $this->calculateHeader($parameters, self::API_URL . '/' . $url);
307
308 if($method == 'POST')
309 {
310 $options[CURLOPT_POST] = true;
311 $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters);
312 }
313
314 else
315 {
316 // reset post
317 $options[CURLOPT_POST] = 0;
318 unset($options[CURLOPT_POSTFIELDS]);
319
320 // add the parameters into the querystring
321 if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters);
322 }
323
324 // set options
325 $options[CURLOPT_URL] = self::API_URL . '/' . $url;
326 $options[CURLOPT_PORT] = self::API_PORT;
327 $options[CURLOPT_USERAGENT] = $this->getUserAgent();
328 if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
329 $options[CURLOPT_RETURNTRANSFER] = true;
330 $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
331 $options[CURLOPT_SSL_VERIFYPEER] = false;
332 $options[CURLOPT_SSL_VERIFYHOST] = false;
333 $options[CURLOPT_HTTPHEADER] = array('Expect:');
334
335 // init
336 $this->curl = curl_init();
337
338 // set options
339 curl_setopt_array($this->curl, $options);
340
341 // execute
342 $response = curl_exec($this->curl);
343 $headers = curl_getinfo($this->curl);
344
345 // fetch errors
346 $errorNumber = curl_errno($this->curl);
347 $errorMessage = curl_error($this->curl);
348
349 // error?
350 if($errorNumber != '') throw new DropboxException($errorMessage, $errorNumber);
351
352 // return
353 if($expectJSON) return json_decode($response, true);
354
355 // fallback
356 return $response;
357 }
358
359
360 /**
361 * Make the call
362 *
363 * @return string
364 * @param string $url The url to call.
365 * @param array[optional] $parameters Optional parameters.
366 * @param bool[optional] $method The method to use. Possible values are GET, POST.
367 * @param string[optional] $filePath The path to the file to upload.
368 * @param bool[optional] $expectJSON Do we expect JSON?
369 * @param bool[optional] $isContent Is this content?
370 */
371 private function doCall($url, array $parameters = null, $method = 'GET', $filePath = null, $expectJSON = true, $isContent = false)
372 {
373 // allowed methods
374 $allowedMethods = array('GET', 'POST');
375
376 // redefine
377 $url = (string) $url;
378 $parameters = (array) $parameters;
379 $method = (string) $method;
380 $expectJSON = (bool) $expectJSON;
381
382 // validate method
383 if(!in_array($method, $allowedMethods)) throw new DropboxException('Unknown method (' . $method . '). Allowed methods are: ' . implode(', ', $allowedMethods));
384
385 // append default parameters
386 $oauth['oauth_consumer_key'] = $this->getApplicationKey();
387 $oauth['oauth_nonce'] = md5(microtime() . rand());
388 $oauth['oauth_timestamp'] = time();
389 $oauth['oauth_token'] = $this->getOAuthToken();
390 $oauth['oauth_signature_method'] = 'HMAC-SHA1';
391 $oauth['oauth_version'] = '1.0';
392
393 // set data
394 $data = $oauth;
395 if(!empty($parameters))
396 {
397 // convert to UTF-8
398 foreach($parameters as &$value) $value = utf8_encode($value);
399
400 // merge
401 $data = array_merge($data, $parameters);
402 }
403
404 if($filePath != null)
405 {
406 // process file
407 $fileInfo = pathinfo($filePath);
408
409 // add to the data
410 $data['file'] = $fileInfo['basename'];
411
412 }
413
414 // calculate the base string
415 if($isContent) $base = $this->calculateBaseString(self::API_CONTENT_URL . '/' . $url, $method, $data);
416 else $base = $this->calculateBaseString(self::API_URL . '/' . $url, $method, $data);
417
418 // based on the method, we should handle the parameters in a different way
419 if($method == 'POST')
420 {
421 // file provided?
422 if($filePath != null)
423 {
424 // build a boundary
425 $boundary = md5(time());
426
427 // init var
428 $content = '--' . $boundary . "\r\n";
429
430 // set file
431 $content .= 'Content-Disposition: form-data; name=file; filename="' . $fileInfo['basename'] . '"' . "\r\n";
432 $content .= 'Content-Type: application/octet-stream' . "\r\n";
433 $content .= "\r\n";
434 $content .= file_get_contents($filePath);
435 $content .= "\r\n";
436 $content .= "--" . $boundary . '--';
437
438 // build headers
439 $headers[] = 'Content-Type: multipart/form-data; boundary=' . $boundary;
440 $headers[] = 'Content-Length: ' . strlen($content);
441
442 // set content
443 $options[CURLOPT_POSTFIELDS] = $content;
444 }
445
446 // no file
447 else $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters);
448
449 // enable post
450 $options[CURLOPT_POST] = 1;
451 }
452
453 else
454 {
455 // reset post
456 $options[CURLOPT_POST] = 0;
457 unset($options[CURLOPT_POSTFIELDS]);
458 $url=str_replace("%2F", "/", rawurlencode($url));
459
460 // add the parameters into the querystring
461 if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters);
462 }
463
464 // add sign into the parameters
465 $oauth['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base);
466
467 if($isContent) $headers[] = $this->calculateHeader($oauth, self::API_CONTENT_URL . '/' . $url);
468 else $headers[] = $this->calculateHeader($oauth, self::API_URL . '/' . $url);
469 $headers[] = 'Expect:';
470
471 // set options
472 if($isContent) $options[CURLOPT_URL] = self::API_CONTENT_URL . '/' . $url;
473 else $options[CURLOPT_URL] = self::API_URL . '/' . $url;
474 $options[CURLOPT_PORT] = self::API_PORT;
475 $options[CURLOPT_USERAGENT] = $this->getUserAgent();
476 if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
477 $options[CURLOPT_RETURNTRANSFER] = true;
478 $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
479 $options[CURLOPT_SSL_VERIFYPEER] = false;
480 $options[CURLOPT_SSL_VERIFYHOST] = false;
481 $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
482 $options[CURLOPT_HTTPHEADER] = $headers;
483 // init
484 if($this->curl == null) $this->curl = curl_init();
485
486 // set options
487 curl_setopt_array($this->curl, $options);
488
489 // execute
490 $response = curl_exec($this->curl);
491 $headers = curl_getinfo($this->curl);
492
493 // fetch errors
494 $errorNumber = curl_errno($this->curl);
495 $errorMessage = curl_error($this->curl);
496
497 if(!$expectJSON && $isContent)
498 {
499 // is it JSON?
500 $json = @json_decode($response, true);
501 if($json !== false && isset($json['error'])) throw new DropboxException($json['error']);
502
503 // set return
504 $return['content_type'] = $headers['content_type'];
505 $return['data'] = base64_encode($response);
506
507 // return
508 return $return;
509 }
510
511 // we don't expect JSON, return the response
512 if(!$expectJSON) return $response;
513
514 // replace ids with their string values, added because of some PHP-version can't handle these large values
515 $response = preg_replace('/id":(\d+)/', 'id":"\1"', $response);
516
517 // we expect JSON, so decode it
518 $json = @json_decode($response, true);
519
520 // validate JSON
521 if($json === null)
522 {
523 // should we provide debug information
524 if(self::DEBUG)
525 {
526 // make it output proper
527 echo '<pre>';
528
529 // dump the header-information
530 var_dump($headers);
531
532 // dump the error
533 var_dump($errorMessage);
534
535 // dump the raw response
536 var_dump($response);
537
538 // end proper format
539 echo '</pre>';
540 }
541
542 // throw exception
543 throw new DropboxException('Invalid response.');
544 }
545
546 // any error
547 if(isset($json['error']))
548 {
549 // should we provide debug information
550 if(self::DEBUG)
551 {
552 // make it output proper
553 echo '<pre>';
554
555 // dump the header-information
556 var_dump($headers);
557
558 // dump the raw response
559 var_dump($response);
560
561 // end proper format
562 echo '</pre>';
563 }
564
565 if(isset($json['error']) && is_string($json['error'])) $message = $json['error'];
566 elseif(isset($json['error']['hash']) && $json['error']['hash'] != '') $message = (string) $json['error']['hash'];
567 else $message = 'Invalid response.';
568
569 // throw exception
570 throw new DropboxException($message);
571 }
572
573 // return
574 return $json;
575 }
576
577
578 /**
579 * Get the application key
580 *
581 * @return string
582 */
583 private function getApplicationKey()
584 {
585 return $this->applicationKey;
586 }
587
588
589 /**
590 * Get the application secret
591 *
592 * @return string
593 */
594 private function getApplicationSecret()
595 {
596 return $this->applicationSecret;
597 }
598
599
600 /**
601 * Get the oAuth-token
602 *
603 * @return string
604 */
605 private function getOAuthToken()
606 {
607 return $this->oAuthToken;
608 }
609
610
611 /**
612 * Get the oAuth-token-secret
613 *
614 * @return string
615 */
616 private function getOAuthTokenSecret()
617 {
618 return $this->oAuthTokenSecret;
619 }
620
621
622 /**
623 * Get the timeout
624 *
625 * @return int
626 */
627 public function getTimeOut()
628 {
629 return (int) $this->timeOut;
630 }
631
632
633 /**
634 * Get the useragent that will be used. Our version will be prepended to yours.
635 * It will look like: "PHP Dropbox/<version> <your-user-agent>"
636 *
637 * @return string
638 */
639 public function getUserAgent()
640 {
641 return (string) 'PHP Dropbox/' . self::VERSION . ' ' . $this->userAgent;
642 }
643
644
645 /**
646 * Set the application key
647 *
648 * @return void
649 * @param string $key The application key to use.
650 */
651 private function setApplicationKey($key)
652 {
653 $this->applicationKey = (string) $key;
654 }
655
656
657 /**
658 * Set the application secret
659 *
660 * @return void
661 * @param string $secret The application secret to use.
662 */
663 private function setApplicationSecret($secret)
664 {
665 $this->applicationSecret = (string) $secret;
666 }
667
668
669 /**
670 * Set the oAuth-token
671 *
672 * @return void
673 * @param string $token The token to use.
674 */
675 public function setOAuthToken($token)
676 {
677 $this->oAuthToken = (string) $token;
678 }
679
680
681 /**
682 * Set the oAuth-secret
683 *
684 * @return void
685 * @param string $secret The secret to use.
686 */
687 public function setOAuthTokenSecret($secret)
688 {
689 $this->oAuthTokenSecret = (string) $secret;
690 }
691
692
693 /**
694 * Set the timeout
695 *
696 * @return void
697 * @param int $seconds The timeout in seconds.
698 */
699 public function setTimeOut($seconds)
700 {
701 $this->timeOut = (int) $seconds;
702 }
703
704
705 /**
706 * Get the useragent that will be used. Our version will be prepended to yours.
707 * It will look like: "PHP Dropbox/<version> <your-user-agent>"
708 *
709 * @return void
710 * @param string $userAgent Your user-agent, it should look like <app-name>/<app-version>.
711 */
712 public function setUserAgent($userAgent)
713 {
714 $this->userAgent = (string) $userAgent;
715 }
716
717
718 /**
719 * Build the signature for the data
720 *
721 * @return string
722 * @param string $key The key to use for signing.
723 * @param string $data The data that has to be signed.
724 */
725 private function hmacsha1($key, $data)
726 {
727 return base64_encode(hash_hmac('SHA1', $data, $key, true));
728 }
729
730
731 /**
732 * URL-encode method for internatl use
733 *
734 * @return string
735 * @param mixed $value The value to encode.
736 */
737 private static function urlencode_rfc3986($value)
738 {
739 if(is_array($value)) return array_map(array('Dropbox', 'urlencode_rfc3986'), $value);
740 else
741 {
742 $search = array('+', ' ', '%7E', '%');
743 $replace = array('%20', '%20', '~', '%25');
744
745 return str_replace($search, $replace, rawurlencode($value));
746 }
747 }
748
749
750 // oauth resources
751 /**
752 * Call for obtaining an OAuth request token.
753 * Returns a request token and the corresponding request token secret. This token and secret cannot be used to sign requests for the /metadata and /file content API calls.
754 * Their only purpose is for signing a request to oauth/access_token once the user has gone through the application authorization steps provided by oauth/authorize.
755 *
756 * @return array
757 */
758 public function oAuthRequestToken()
759 {
760 // make the call
761 $response = $this->doOAuthCall('1/oauth/request_token', null, 'POST', false);
762
763 // process response
764 $response = (array) explode('&', $response);
765 $return = array();
766
767 // loop chunks
768 foreach($response as $chunk)
769 {
770 // split again
771 $chunks = explode('=', $chunk, 2);
772
773 // store return
774 if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1];
775 }
776
777 // return
778 return $return;
779 }
780
781
782 /**
783 * Redirect the user to the oauth/authorize location so that Dropbox can authenticate the user and ask whether or not the user wants to authorize the application to access
784 * file metadata and content on its behalf. oauth/authorize is not an API call per se, because it does not have a return value, but rather directs the user to a page on
785 * api.dropbox.com where they are provided means to log in to Dropbox and grant authority to the application requesting it.
786 * The page served by oauth/authorize should be presented to the user through their web browser.
787 * Please note, without directing the user to a Dropbox-provided page via oauth/authorize, it is impossible for your application to use the request token it received
788 * via oauth/request_token to obtain an access token from oauth/access_token.
789 *
790 * @return void
791 * @param string $oauthToken The request token of the application requesting authority from a user.
792 * @param string[optional] $oauthCallback After the user authorizes an application, the user is redirected to the application-served URL provided by this parameter.
793 */
794 public function oAuthAuthorize($oauthToken, $oauthCallback = null)
795 {
796 // build parameters
797 $parameters = array();
798 $parameters['oauth_token'] = (string) $oauthToken;
799 if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback;
800
801 // build url
802 $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters);
803
804 // redirect
805 header('Location: ' . $url);
806 exit;
807 }
808
809 public function mwp_oAuthAuthorize($oauthToken, $oauthCallback = null)
810 {
811 // build parameters
812 $parameters = array();
813 $parameters['oauth_token'] = (string) $oauthToken;
814 if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback;
815
816 // build url
817 $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters);
818
819 return $url;
820 }
821
822 /**
823 * This call returns a access token and the corresponding access token secret.
824 * Upon return, the authorization process is now complete and the access token and corresponding secret are used to sign requests for the metadata and file content API calls.
825 *
826 * @return array
827 * @param string $oauthToken The token returned after authorizing.
828 */
829 public function oAuthAccessToken($oauthToken)
830 {
831 // build parameters
832 $parameters = array();
833 $parameters['oauth_token'] = (string) $oauthToken;
834
835 // make the call
836 $response = $this->doOAuthCall('1/oauth/access_token', $parameters, 'POST', false);
837
838 // process response
839 $response = (array) explode('&', $response);
840 $return = array();
841
842 // loop chunks
843 foreach($response as $chunk)
844 {
845 // split again
846 $chunks = explode('=', $chunk, 2);
847
848 // store return
849 if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1];
850 }
851
852 // return
853 return $return;
854 }
855
856
857 // token resources
858 /**
859 * The token call provides a consumer/secret key pair you can use to consistently access the user's account.
860 * This is the preferred method of authentication over storing the username and password.
861 * Use the key pair as a signature with every subsequent call.
862 * The request must be signed using the application's developer and secret key token. Request or access tokens are necessary.
863 *
864 * Warning: DO NOT STORE THE USER'S PASSWORD! The way this call works is you call it once with the user's email and password and then
865 * keep the token around for later. You do NOT (I repeat NOT) call this before everything you do or on each program startup.
866 * We watch for this and will shut down your application with little notice if we catch you.
867 * In fact, the Objective-C code does this for you so you can't get it wrong.
868 *
869 * @return array Upon successful verification of the user's credentials, returns an array representation of the access token and secret.
870 * @param string $email The email account of the user.
871 * @param string $password The password of the user.
872 */
873 public function token($email, $password)
874 {
875 // build parameters
876 $parameters = array();
877 $parameters['email'] = (string) $email;
878 $parameters['password'] = (string) $password;
879
880 // make the call
881 $response = (array) $this->doOAuthCall('1/token', $parameters);
882
883 // validate and set
884 if(isset($response['token'])) $this->setOAuthToken($response['token']);
885 if(isset($response['secret'])) $this->setOAuthTokenSecret($response['secret']);
886
887 // return
888 return $response;
889 }
890
891
892 // account resources
893 /**
894 * Given a set of account information, the account call allows an application to create a new Dropbox user account.
895 * This is useful for situations where the trusted third party application is possibly the user's first interaction with Dropbox.
896 *
897 * @return bool
898 * @param string $email The email account of the user.
899 * @param string $password The password for the user.
900 * @param string $firstName The user's first name.
901 * @param string $lastName The user's last name.
902 */
903 public function account($email, $password, $firstName, $lastName)
904 {
905 // build parameters
906 $parameters['email'] = (string) $email;
907 $parameters['first_name'] = (string) $firstName;
908 $parameters['last_name'] = (string) $lastName;
909 $parameters['password'] = (string) $password;
910
911 return (bool) ($this->doCall('1/account', $parameters, 'POST', null, false) == 'OK');
912 }
913
914
915 /**
916 * Get the user account information.
917 *
918 * @return array
919 */
920 public function accountInfo()
921 {
922 // make the call
923 return (array) $this->doCall('1/account/info');
924 }
925
926
927 // files & metadata
928 /**
929 * Retrieves file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox.
930 *
931 * @return string
932 * @param string $path Path of the directory wherin the file is located.
933 * @param bool[optional] $sandbox Sandbox mode?
934 */
935 public function filesGet($path, $sandbox = false)
936 {
937 // build url
938 $url = '1/files/';
939 $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
940 $url .= trim((string) $path, '/');
941
942 // make the call
943 return $this->doCall($url, null, 'GET', null, false, true);
944 }
945
946
947 /**
948 * Uploads file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox.
949 *
950 * @return bool
951 * @param string $path Path of the directory wherin the file should be uploaded.
952 * @param string $localFile Path to the local file.
953 * @param bool[optional] $sandbox Sandbox mode?
954 */
955 public function filesPost($path, $localFile, $sandbox = false)
956 {
957 // build url
958 $url = '1/files/';
959 $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
960 $url .= trim((string) $path, '/');
961
962 // make the call
963 $return = $this->doCall($url, null, 'POST', $localFile, true, true);
964 // return the result
965 return (bool) (isset($return['size']) && $return['size'] == 'winner!');
966 }
967
968
969 /**
970 * Returns metadata for the file or directory at the given <path> location relative to the user's Dropbox or
971 * the user's application sandbox. If <path> represents a directory and the list parameter is true, the metadata will
972 * also include a listing of metadata for the directory's contents.
973 *
974 * @return array
975 * @param string[optional] $path The path to the file/director to get the metadata for.
976 * @param int[optional] $fileLimit When listing a directory, the service will not report listings containing more than $fileLimit files.
977 * @param bool[optional] $hash Listing return values include a hash representing the state of the directory's contents.
978 * @param bool[optional] $list If true, this call returns a list of metadata representations for the contents of the directory. If false, this call returns the metadata for the directory itself.
979 * @param bool[optional] $sandbox Sandbox mode?
980 */
981 public function metadata($path = '', $fileLimit = 10000, $hash = false, $list = true, $sandbox = false)
982 {
983 // build url
984 $url = '1/metadata/';
985 $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
986 $url .= trim((string) $path, '/');
987
988 // build parameters
989 $parameters = null;
990 $parameters['file_limit'] = (int) $fileLimit;
991 if((bool) $hash) $parameters['hash'] = '';
992 $parameters['list'] = ($list) ? 'true': 'false';
993
994 // make the call
995 return (array) $this->doCall($url, $parameters);
996 }
997
998
999 /**
1000 * Get a minimized thumbnail for a photo.
1001 *
1002 * @return string Will return a base64_encode string with the JPEG-data
1003 * @param string $path The path to the photo.
1004 * @param string[optional] $size The size, possible values are: 'small' (32x32), 'medium' (64x64), 'large' (128x128).
1005 */
1006 public function thumbnails($path, $size = 'small')
1007 {
1008 // build url
1009 $url = '1/thumbnails/dropbox/';
1010 $url .= trim((string) $path, '/');
1011
1012 // build parameters
1013 $parameters['size'] = (string) $size;
1014
1015 // make the call
1016 return $this->doCall($url, $parameters, 'GET', null, false, true);
1017 }
1018
1019
1020 // file operations
1021 /**
1022 * Copy a file or folder to a new location.
1023 *
1024 * @return array
1025 * @param string $fromPath fromPath specifies either a file or folder to be copied to the location specified by toPath. This path is interpreted relative to the location specified by root.
1026 * @param string $toPath toPath specifies the destination path including the new name for file or folder. This path is interpreted relative to the location specified by root.
1027 * @param bool[optional] $sandbox Sandbox mode?
1028 */
1029 public function fileopsCopy($fromPath, $toPath, $sandbox = false)
1030 {
1031 // build url
1032 $url = '1/fileops/copy';
1033
1034 // build parameters
1035 $parameters['from_path'] = (string) $fromPath;
1036 $parameters['to_path'] = (string) $toPath;
1037 $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1038
1039 // make the call
1040 return $this->doCall($url, $parameters, 'POST');
1041 }
1042
1043
1044 /**
1045 * Create a folder relative to the user's Dropbox root or the user's application sandbox folder.
1046 *
1047 * @return array
1048 * @param string $path The path to the new folder to create, relative to root.
1049 * @param bool[optional] $sandbox Sandbox mode?
1050 */
1051 public function fileopsCreateFolder($path, $sandbox = false)
1052 {
1053 // build url
1054 $url = '1/fileops/create_folder';
1055
1056 // build parameters
1057 $parameters['path'] = trim((string) $path, '/');
1058 $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1059
1060 // make the call
1061 return $this->doCall($url, $parameters, 'POST');
1062 }
1063
1064
1065 /**
1066 * Deletes a file or folder.
1067 *
1068 * @return array
1069 * @param string $path path specifies either a file or folder to be deleted. This path is interpreted relative to the location specified by root.
1070 * @param bool[optional] $sandbox Sandbox mode?
1071 */
1072 public function fileopsDelete($path, $sandbox = false)
1073 {
1074 // build url
1075 $url = '1/fileops/delete';
1076
1077 // build parameters
1078 $parameters['path'] = trim((string) $path, '/');
1079 $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1080 // make the call
1081 return $this->doCall($url, $parameters, 'POST');
1082 }
1083
1084
1085 /**
1086 * Move a file or folder to a new location.
1087 *
1088 * @return array
1089 * @param string $fromPath fromPath specifies either a file or folder to be copied to the location specified by toPath. This path is interpreted relative to the location specified by root.
1090 * @param string $toPath toPath specifies the destination path including the new name for file or folder. This path is interpreted relative to the location specified by root.
1091 * @param bool[optional] $sandbox Sandbox mode?
1092 */
1093 public function fileopsMove($fromPath, $toPath, $sandbox = false)
1094 {
1095 // build url
1096 $url = '1/fileops/move';
1097
1098 // build parameters
1099 $parameters['from_path'] = (string) $fromPath;
1100 $parameters['to_path'] = (string) $toPath;
1101 $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1102
1103 // make the call
1104 return $this->doCall($url, $parameters, 'POST');
1105 }
1106
1107 function _log($mixed)
1108 {
1109 if (is_array($mixed)) {
1110 $mixed = print_r($mixed, 1);
1111 } else if (is_object($mixed)) {
1112 ob_start();
1113 var_dump($mixed);
1114 $mixed = ob_get_clean();
1115 }
1116
1117 $handle = fopen(dirname(__FILE__) . '/log', 'a');
1118 fwrite($handle, $mixed . PHP_EOL);
1119 fclose($handle);
1120 }
1121 }
1122
1123
1124 /**
1125 * Dropbox Exception class
1126 *
1127 * @author Tijs Verkoyen <[email protected]>
1128 */
1129 class DropboxException extends Exception
1130 {
1131 }
1132
1133 ?>
1134
1135