* @version 1.0.5 * * @copyright Copyright (c), Tijs Verkoyen. All rights reserved. * @license BSD License */ class Dropbox { // internal constant to enable/disable debugging const DEBUG = false; // url for the dropbox-api const API_URL = 'https://api.dropbox.com'; const API_AUTH_URL = 'https://www.dropbox.com'; const API_CONTENT_URL = 'https://api-content.dropbox.com'; // port for the dropbox-api const API_PORT = 443; // current version const VERSION = '1.0.5'; /** * A cURL instance * * @var resource */ private $curl; /** * The application key * * @var string */ private $applicationKey; /** * The application secret * * @var string */ private $applicationSecret; /** * The oAuth-token * * @var string */ private $oAuthToken = ''; /** * The oAuth-token-secret * * @var string */ private $oAuthTokenSecret = ''; /** * The timeout * * @var int */ private $timeOut = 60; /** * The user agent * * @var string */ private $userAgent; // class methods /** * Default constructor * * @return void * @param string $applicationKey The application key to use. * @param string $applicationSecret The application secret to use. */ public function __construct($applicationKey, $applicationSecret) { $this->setApplicationKey($applicationKey); $this->setApplicationSecret($applicationSecret); } /** * Default destructor * * @return void */ public function __destruct() { if($this->curl != null) curl_close($this->curl); } /** * Format the parameters as a querystring * * @return string * @param array $parameters The parameters to pass. */ private function buildQuery(array $parameters) { // no parameters? if(empty($parameters)) return ''; // encode the keys $keys = self::urlencode_rfc3986(array_keys($parameters)); // encode the values $values = self::urlencode_rfc3986(array_values($parameters)); // reset the parameters $parameters = array_combine($keys, $values); // sort parameters by key uksort($parameters, 'strcmp'); // loop parameters foreach($parameters as $key => $value) { // sort by value if(is_array($value)) $parameters[$key] = natsort($value); } // process parameters foreach($parameters as $key => $value) $chunks[] = $key . '=' . str_replace('%25', '%', $value); // return return implode('&', $chunks); } /** * All OAuth 1.0 requests use the same basic algorithm for creating a signature base string and a signature. * 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, * complete with path (but not query parameters), followed by an ampersand ("&"). * 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), * including the OAuth parameters necessary for negotiation with the request at hand, and sort them in lexicographical order by first parameter name and * 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. * 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 * URL-escaped ampersand sign, "%26". * * @return string * @param string $url The url to use. * @param string $method The method that will be called. * @param array $parameters The parameters to pass. */ private function calculateBaseString($url, $method, array $parameters) { // redefine $url = (string) $url; $parameters = (array) $parameters; // init var $pairs = array(); $chunks = array(); // sort parameters by key uksort($parameters, 'strcmp'); // loop parameters foreach($parameters as $key => $value) { // sort by value if(is_array($value)) $parameters[$key] = natsort($value); } // process queries foreach($parameters as $key => $value) { // only add if not already in the url if(substr_count($url, $key . '=' . $value) == 0) $chunks[] = self::urlencode_rfc3986($key) . '%3D' . self::urlencode_rfc3986($value); } $urlChunks = explode('/', $url); $i = 0; foreach($urlChunks as &$chunk) { if($i > 4) $chunk = self::urlencode_rfc3986($chunk); else $chunk = urlencode($chunk); $i++; } // build base $base = $method . '&'; $base .= implode('%2F', $urlChunks); $base .= (substr_count($url, '?')) ? '%26' : '&'; $base .= implode('%26', $chunks); $base = str_replace(array('%3F', '%20'), array('&', '%2520'), $base); // return return $base; } /** * Build the Authorization header * @later: fix me * * @return string * @param array $parameters The parameters to pass. * @param string $url The url to use. */ private function calculateHeader(array $parameters, $url) { // redefine $url = (string) $url; // divide into parts $parts = parse_url($url); // init var $chunks = array(); // process queries foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', self::urlencode_rfc3986($key) . '="' . self::urlencode_rfc3986($value) . '"'); $parts['path']=str_replace("%2F", "/", rawurlencode($parts['path'])); // build return $return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", '; $return .= implode(',', $chunks); // prepend name and OAuth part return $return; } /** * Make an call to the oAuth * @todo refactor me * * @return array * @param string $url The url that has to be called. * @param array[optional] $parameters The parameters to pass. * @param string[optional] $method Which HTTP-method should we use? Possible values are POST, GET. * @param bool[optional] $expectJSON Do we expect JSON? */ private function doOAuthCall($url, array $parameters = null, $method = 'POST', $expectJSON = true) { // redefine $url = (string) $url; // append default parameters $parameters['oauth_consumer_key'] = $this->getApplicationKey(); $parameters['oauth_nonce'] = md5(microtime() . rand()); $parameters['oauth_timestamp'] = time(); $parameters['oauth_signature_method'] = 'HMAC-SHA1'; $parameters['oauth_version'] = '1.0'; // calculate the base string $base = $this->calculateBaseString(self::API_URL . '/' . $url, 'POST', $parameters); // add sign into the parameters $parameters['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base); // calculate header $header = $this->calculateHeader($parameters, self::API_URL . '/' . $url); if($method == 'POST') { $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters); } else { // reset post $options[CURLOPT_POST] = 0; unset($options[CURLOPT_POSTFIELDS]); // add the parameters into the querystring if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters); } // set options $options[CURLOPT_URL] = self::API_URL . '/' . $url; $options[CURLOPT_PORT] = self::API_PORT; $options[CURLOPT_USERAGENT] = $this->getUserAgent(); if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true; $options[CURLOPT_RETURNTRANSFER] = true; $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut(); $options[CURLOPT_SSL_VERIFYPEER] = false; $options[CURLOPT_SSL_VERIFYHOST] = false; $options[CURLOPT_HTTPHEADER] = array('Expect:'); // init $this->curl = curl_init(); // set options curl_setopt_array($this->curl, $options); // execute $response = curl_exec($this->curl); $headers = curl_getinfo($this->curl); // fetch errors $errorNumber = curl_errno($this->curl); $errorMessage = curl_error($this->curl); // error? if($errorNumber != '') throw new DropboxException($errorMessage, $errorNumber); // return if($expectJSON) return json_decode($response, true); // fallback return $response; } /** * Make the call * * @return string * @param string $url The url to call. * @param array[optional] $parameters Optional parameters. * @param bool[optional] $method The method to use. Possible values are GET, POST. * @param string[optional] $filePath The path to the file to upload. * @param bool[optional] $expectJSON Do we expect JSON? * @param bool[optional] $isContent Is this content? */ private function doCall($url, array $parameters = null, $method = 'GET', $filePath = null, $expectJSON = true, $isContent = false) { // allowed methods $allowedMethods = array('GET', 'POST'); // redefine $url = (string) $url; $parameters = (array) $parameters; $method = (string) $method; $expectJSON = (bool) $expectJSON; // validate method if(!in_array($method, $allowedMethods)) throw new DropboxException('Unknown method (' . $method . '). Allowed methods are: ' . implode(', ', $allowedMethods)); // append default parameters $oauth['oauth_consumer_key'] = $this->getApplicationKey(); $oauth['oauth_nonce'] = md5(microtime() . rand()); $oauth['oauth_timestamp'] = time(); $oauth['oauth_token'] = $this->getOAuthToken(); $oauth['oauth_signature_method'] = 'HMAC-SHA1'; $oauth['oauth_version'] = '1.0'; // set data $data = $oauth; if(!empty($parameters)) { // convert to UTF-8 foreach($parameters as &$value) $value = utf8_encode($value); // merge $data = array_merge($data, $parameters); } if($filePath != null) { // process file $fileInfo = pathinfo($filePath); // add to the data $data['file'] = $fileInfo['basename']; } // calculate the base string if($isContent) $base = $this->calculateBaseString(self::API_CONTENT_URL . '/' . $url, $method, $data); else $base = $this->calculateBaseString(self::API_URL . '/' . $url, $method, $data); // based on the method, we should handle the parameters in a different way if($method == 'POST') { // file provided? if($filePath != null) { // build a boundary $boundary = md5(time()); // init var $content = '--' . $boundary . "\r\n"; // set file $content .= 'Content-Disposition: form-data; name=file; filename="' . $fileInfo['basename'] . '"' . "\r\n"; $content .= 'Content-Type: application/octet-stream' . "\r\n"; $content .= "\r\n"; $content .= file_get_contents($filePath); $content .= "\r\n"; $content .= "--" . $boundary . '--'; // build headers $headers[] = 'Content-Type: multipart/form-data; boundary=' . $boundary; $headers[] = 'Content-Length: ' . strlen($content); // set content $options[CURLOPT_POSTFIELDS] = $content; } // no file else $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters); // enable post $options[CURLOPT_POST] = 1; } else { // reset post $options[CURLOPT_POST] = 0; unset($options[CURLOPT_POSTFIELDS]); $url=str_replace("%2F", "/", rawurlencode($url)); // add the parameters into the querystring if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters); } // add sign into the parameters $oauth['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base); if($isContent) $headers[] = $this->calculateHeader($oauth, self::API_CONTENT_URL . '/' . $url); else $headers[] = $this->calculateHeader($oauth, self::API_URL . '/' . $url); $headers[] = 'Expect:'; // set options if($isContent) $options[CURLOPT_URL] = self::API_CONTENT_URL . '/' . $url; else $options[CURLOPT_URL] = self::API_URL . '/' . $url; $options[CURLOPT_PORT] = self::API_PORT; $options[CURLOPT_USERAGENT] = $this->getUserAgent(); if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true; $options[CURLOPT_RETURNTRANSFER] = true; $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut(); $options[CURLOPT_SSL_VERIFYPEER] = false; $options[CURLOPT_SSL_VERIFYHOST] = false; $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; $options[CURLOPT_HTTPHEADER] = $headers; // init if($this->curl == null) $this->curl = curl_init(); // set options curl_setopt_array($this->curl, $options); // execute $response = curl_exec($this->curl); $headers = curl_getinfo($this->curl); // fetch errors $errorNumber = curl_errno($this->curl); $errorMessage = curl_error($this->curl); if(!$expectJSON && $isContent) { // is it JSON? $json = @json_decode($response, true); if($json !== false && isset($json['error'])) throw new DropboxException($json['error']); // set return $return['content_type'] = $headers['content_type']; $return['data'] = base64_encode($response); // return return $return; } // we don't expect JSON, return the response if(!$expectJSON) return $response; // replace ids with their string values, added because of some PHP-version can't handle these large values $response = preg_replace('/id":(\d+)/', 'id":"\1"', $response); // we expect JSON, so decode it $json = @json_decode($response, true); // validate JSON if($json === null) { // should we provide debug information if(self::DEBUG) { // make it output proper echo '
';

				// dump the header-information
				var_dump($headers);

				// dump the error
				var_dump($errorMessage);

				// dump the raw response
				var_dump($response);

				// end proper format
				echo '
'; } // throw exception throw new DropboxException('Invalid response.'); } // any error if(isset($json['error'])) { // should we provide debug information if(self::DEBUG) { // make it output proper echo '
';

				// dump the header-information
				var_dump($headers);

				// dump the raw response
				var_dump($response);

				// end proper format
				echo '
'; } if(isset($json['error']) && is_string($json['error'])) $message = $json['error']; elseif(isset($json['error']['hash']) && $json['error']['hash'] != '') $message = (string) $json['error']['hash']; else $message = 'Invalid response.'; // throw exception throw new DropboxException($message); } // return return $json; } /** * Get the application key * * @return string */ private function getApplicationKey() { return $this->applicationKey; } /** * Get the application secret * * @return string */ private function getApplicationSecret() { return $this->applicationSecret; } /** * Get the oAuth-token * * @return string */ private function getOAuthToken() { return $this->oAuthToken; } /** * Get the oAuth-token-secret * * @return string */ private function getOAuthTokenSecret() { return $this->oAuthTokenSecret; } /** * Get the timeout * * @return int */ public function getTimeOut() { return (int) $this->timeOut; } /** * Get the useragent that will be used. Our version will be prepended to yours. * It will look like: "PHP Dropbox/ " * * @return string */ public function getUserAgent() { return (string) 'PHP Dropbox/' . self::VERSION . ' ' . $this->userAgent; } /** * Set the application key * * @return void * @param string $key The application key to use. */ private function setApplicationKey($key) { $this->applicationKey = (string) $key; } /** * Set the application secret * * @return void * @param string $secret The application secret to use. */ private function setApplicationSecret($secret) { $this->applicationSecret = (string) $secret; } /** * Set the oAuth-token * * @return void * @param string $token The token to use. */ public function setOAuthToken($token) { $this->oAuthToken = (string) $token; } /** * Set the oAuth-secret * * @return void * @param string $secret The secret to use. */ public function setOAuthTokenSecret($secret) { $this->oAuthTokenSecret = (string) $secret; } /** * Set the timeout * * @return void * @param int $seconds The timeout in seconds. */ public function setTimeOut($seconds) { $this->timeOut = (int) $seconds; } /** * Get the useragent that will be used. Our version will be prepended to yours. * It will look like: "PHP Dropbox/ " * * @return void * @param string $userAgent Your user-agent, it should look like /. */ public function setUserAgent($userAgent) { $this->userAgent = (string) $userAgent; } /** * Build the signature for the data * * @return string * @param string $key The key to use for signing. * @param string $data The data that has to be signed. */ private function hmacsha1($key, $data) { return base64_encode(hash_hmac('SHA1', $data, $key, true)); } /** * URL-encode method for internatl use * * @return string * @param mixed $value The value to encode. */ private static function urlencode_rfc3986($value) { if(is_array($value)) return array_map(array('Dropbox', 'urlencode_rfc3986'), $value); else { $search = array('+', ' ', '%7E', '%'); $replace = array('%20', '%20', '~', '%25'); return str_replace($search, $replace, rawurlencode($value)); } } // oauth resources /** * Call for obtaining an OAuth request token. * 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. * 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. * * @return array */ public function oAuthRequestToken() { // make the call $response = $this->doOAuthCall('1/oauth/request_token', null, 'POST', false); // process response $response = (array) explode('&', $response); $return = array(); // loop chunks foreach($response as $chunk) { // split again $chunks = explode('=', $chunk, 2); // store return if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1]; } // return return $return; } /** * 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 * 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 * api.dropbox.com where they are provided means to log in to Dropbox and grant authority to the application requesting it. * The page served by oauth/authorize should be presented to the user through their web browser. * 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 * via oauth/request_token to obtain an access token from oauth/access_token. * * @return void * @param string $oauthToken The request token of the application requesting authority from a user. * @param string[optional] $oauthCallback After the user authorizes an application, the user is redirected to the application-served URL provided by this parameter. */ public function oAuthAuthorize($oauthToken, $oauthCallback = null) { // build parameters $parameters = array(); $parameters['oauth_token'] = (string) $oauthToken; if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback; // build url $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters); // redirect header('Location: ' . $url); exit; } public function mwp_oAuthAuthorize($oauthToken, $oauthCallback = null) { // build parameters $parameters = array(); $parameters['oauth_token'] = (string) $oauthToken; if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback; // build url $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters); return $url; } /** * This call returns a access token and the corresponding access token secret. * 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. * * @return array * @param string $oauthToken The token returned after authorizing. */ public function oAuthAccessToken($oauthToken) { // build parameters $parameters = array(); $parameters['oauth_token'] = (string) $oauthToken; // make the call $response = $this->doOAuthCall('1/oauth/access_token', $parameters, 'POST', false); // process response $response = (array) explode('&', $response); $return = array(); // loop chunks foreach($response as $chunk) { // split again $chunks = explode('=', $chunk, 2); // store return if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1]; } // return return $return; } // token resources /** * The token call provides a consumer/secret key pair you can use to consistently access the user's account. * This is the preferred method of authentication over storing the username and password. * Use the key pair as a signature with every subsequent call. * The request must be signed using the application's developer and secret key token. Request or access tokens are necessary. * * 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 * keep the token around for later. You do NOT (I repeat NOT) call this before everything you do or on each program startup. * We watch for this and will shut down your application with little notice if we catch you. * In fact, the Objective-C code does this for you so you can't get it wrong. * * @return array Upon successful verification of the user's credentials, returns an array representation of the access token and secret. * @param string $email The email account of the user. * @param string $password The password of the user. */ public function token($email, $password) { // build parameters $parameters = array(); $parameters['email'] = (string) $email; $parameters['password'] = (string) $password; // make the call $response = (array) $this->doOAuthCall('1/token', $parameters); // validate and set if(isset($response['token'])) $this->setOAuthToken($response['token']); if(isset($response['secret'])) $this->setOAuthTokenSecret($response['secret']); // return return $response; } // account resources /** * Given a set of account information, the account call allows an application to create a new Dropbox user account. * This is useful for situations where the trusted third party application is possibly the user's first interaction with Dropbox. * * @return bool * @param string $email The email account of the user. * @param string $password The password for the user. * @param string $firstName The user's first name. * @param string $lastName The user's last name. */ public function account($email, $password, $firstName, $lastName) { // build parameters $parameters['email'] = (string) $email; $parameters['first_name'] = (string) $firstName; $parameters['last_name'] = (string) $lastName; $parameters['password'] = (string) $password; return (bool) ($this->doCall('1/account', $parameters, 'POST', null, false) == 'OK'); } /** * Get the user account information. * * @return array */ public function accountInfo() { // make the call return (array) $this->doCall('1/account/info'); } // files & metadata /** * Retrieves file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox. * * @return string * @param string $path Path of the directory wherin the file is located. * @param bool[optional] $sandbox Sandbox mode? */ public function filesGet($path, $sandbox = false) { // build url $url = '1/files/'; $url .= ($sandbox) ? 'sandbox/' : 'dropbox/'; $url .= trim((string) $path, '/'); // make the call return $this->doCall($url, null, 'GET', null, false, true); } /** * Uploads file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox. * * @return bool * @param string $path Path of the directory wherin the file should be uploaded. * @param string $localFile Path to the local file. * @param bool[optional] $sandbox Sandbox mode? */ public function filesPost($path, $localFile, $sandbox = false) { // build url $url = '1/files/'; $url .= ($sandbox) ? 'sandbox/' : 'dropbox/'; $url .= trim((string) $path, '/'); // make the call $return = $this->doCall($url, null, 'POST', $localFile, true, true); // return the result return (bool) (isset($return['size']) && $return['size'] == 'winner!'); } /** * Returns metadata for the file or directory at the given location relative to the user's Dropbox or * the user's application sandbox. If represents a directory and the list parameter is true, the metadata will * also include a listing of metadata for the directory's contents. * * @return array * @param string[optional] $path The path to the file/director to get the metadata for. * @param int[optional] $fileLimit When listing a directory, the service will not report listings containing more than $fileLimit files. * @param bool[optional] $hash Listing return values include a hash representing the state of the directory's contents. * @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. * @param bool[optional] $sandbox Sandbox mode? */ public function metadata($path = '', $fileLimit = 10000, $hash = false, $list = true, $sandbox = false) { // build url $url = '1/metadata/'; $url .= ($sandbox) ? 'sandbox/' : 'dropbox/'; $url .= trim((string) $path, '/'); // build parameters $parameters = null; $parameters['file_limit'] = (int) $fileLimit; if((bool) $hash) $parameters['hash'] = ''; $parameters['list'] = ($list) ? 'true': 'false'; // make the call return (array) $this->doCall($url, $parameters); } /** * Get a minimized thumbnail for a photo. * * @return string Will return a base64_encode string with the JPEG-data * @param string $path The path to the photo. * @param string[optional] $size The size, possible values are: 'small' (32x32), 'medium' (64x64), 'large' (128x128). */ public function thumbnails($path, $size = 'small') { // build url $url = '1/thumbnails/dropbox/'; $url .= trim((string) $path, '/'); // build parameters $parameters['size'] = (string) $size; // make the call return $this->doCall($url, $parameters, 'GET', null, false, true); } // file operations /** * Copy a file or folder to a new location. * * @return array * @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. * @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. * @param bool[optional] $sandbox Sandbox mode? */ public function fileopsCopy($fromPath, $toPath, $sandbox = false) { // build url $url = '1/fileops/copy'; // build parameters $parameters['from_path'] = (string) $fromPath; $parameters['to_path'] = (string) $toPath; $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox'; // make the call return $this->doCall($url, $parameters, 'POST'); } /** * Create a folder relative to the user's Dropbox root or the user's application sandbox folder. * * @return array * @param string $path The path to the new folder to create, relative to root. * @param bool[optional] $sandbox Sandbox mode? */ public function fileopsCreateFolder($path, $sandbox = false) { // build url $url = '1/fileops/create_folder'; // build parameters $parameters['path'] = trim((string) $path, '/'); $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox'; // make the call return $this->doCall($url, $parameters, 'POST'); } /** * Deletes a file or folder. * * @return array * @param string $path path specifies either a file or folder to be deleted. This path is interpreted relative to the location specified by root. * @param bool[optional] $sandbox Sandbox mode? */ public function fileopsDelete($path, $sandbox = false) { // build url $url = '1/fileops/delete'; // build parameters $parameters['path'] = trim((string) $path, '/'); $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox'; // make the call return $this->doCall($url, $parameters, 'POST'); } /** * Move a file or folder to a new location. * * @return array * @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. * @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. * @param bool[optional] $sandbox Sandbox mode? */ public function fileopsMove($fromPath, $toPath, $sandbox = false) { // build url $url = '1/fileops/move'; // build parameters $parameters['from_path'] = (string) $fromPath; $parameters['to_path'] = (string) $toPath; $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox'; // make the call return $this->doCall($url, $parameters, 'POST'); } function _log($mixed) { if (is_array($mixed)) { $mixed = print_r($mixed, 1); } else if (is_object($mixed)) { ob_start(); var_dump($mixed); $mixed = ob_get_clean(); } $handle = fopen(dirname(__FILE__) . '/log', 'a'); fwrite($handle, $mixed . PHP_EOL); fclose($handle); } } /** * Dropbox Exception class * * @author Tijs Verkoyen */ class DropboxException extends Exception { } ?>