PageRenderTime 77ms CodeModel.GetById 16ms RepoModel.GetById 2ms app.codeStats 0ms

/DropboxClient.php

https://github.com/agmps17/ICE
PHP | 368 lines | 255 code | 60 blank | 53 comment | 36 complexity | 1a9387d1c897a50d04995acf4a9af573 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * DropPHP - A simple Dropbox client that works without cURL.
  4. *
  5. * http://fabi.me/en/php-projects/dropphp-dropbox-api-client/
  6. *
  7. * @author Fabian Schlieper <fabian@fabi.me>
  8. * @copyright Fabian Schlieper 2012
  9. * @version 1.0
  10. * @license See license.txt
  11. *
  12. */
  13. require_once(dirname(__FILE__)."/OAuthSimple.php");
  14. class DropboxClient {
  15. const API_URL = "https://api.dropbox.com/1/";
  16. const API_CONTENT_URL = "http://api-content.dropbox.com/1/";
  17. const BUFFER_SIZE = 524288;
  18. private $appParams;
  19. private $consumerToken;
  20. private $requestToken;
  21. private $accessToken;
  22. private $locale;
  23. private $rootPath;
  24. function __construct ($app_params, $locale = "en"){
  25. $this->appParams = $app_params;
  26. $this->consumerToken = array('t' => $this->appParams['app_key'], 's' => $this->appParams['app_secret']);
  27. $this->locale = $locale;
  28. $this->rootPath = empty($app_params['app_full_access']) ? "sandbox" : "dropbox";
  29. $this->requestToken = null;
  30. $this->accessToken = null;
  31. }
  32. // ##################################################
  33. // Authorization
  34. function GetRequestToken()
  35. {
  36. if(!empty($this->requestToken))
  37. return $this->requestToken;
  38. $rt = $this->authCall("oauth/request_token");
  39. if(empty($rt))
  40. throw new DropboxException('Could not get request token!');
  41. return ($this->requestToken = array('t'=>$rt['oauth_token'], 's'=>$rt['oauth_token_secret']));
  42. }
  43. function GetAccessToken($request_token)
  44. {
  45. if(!empty($this->accessToken)) return $this->accessToken;
  46. if(empty($request_token)) throw new DropboxException('Passed request token is invalid.');
  47. $at = $this->authCall("oauth/access_token", $request_token);
  48. if(empty($at))
  49. throw new DropboxException('Could not get access token!');
  50. return ($this->accessToken = array('t'=>$at['oauth_token'], 's'=>$at['oauth_token_secret']));
  51. }
  52. function SetAccessToken($token)
  53. {
  54. if(empty($token['t']) || empty($token['s'])) throw new DropboxException('Passed invalid access token.');
  55. $this->accessToken = $token;
  56. }
  57. function IsAuthorized()
  58. {
  59. if(empty($this->accessToken)) return false;
  60. return true;
  61. }
  62. function BuildAuthorizeUrl($return_url)
  63. {
  64. $rt = $this->GetRequestToken();
  65. if(empty($rt)) return false;
  66. return "https://www.dropbox.com/1/oauth/authorize?oauth_token=".$rt['t']."&oauth_callback=".urlencode($return_url);
  67. }
  68. function GetAccountInfo()
  69. {
  70. return $this->apiCall("account/info", "GET", array('hash'=>true));
  71. }
  72. // ##################################################
  73. // API Functions
  74. /**
  75. * Get file list of a dropbox folder.
  76. *
  77. * @access public
  78. * @param string $dropbox_path Dropbox path of the folder
  79. */
  80. public function GetFiles($dropbox_path='', $recursive=false)
  81. {
  82. if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
  83. return $this->getFileTree($dropbox_path, $recursive ? 1000 : 0);
  84. }
  85. /**
  86. * Get file or folder metadata
  87. *
  88. * @access public
  89. * @param dropbox_path (String) Dropbox path of the file or folder
  90. */
  91. public function GetMetadata($dropbox_path)
  92. {
  93. if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
  94. return $this->apiCall("metadata/$this->rootPath/$dropbox_path", "GET");
  95. }
  96. public function GetMedia($dropbox_path)
  97. {
  98. //print_r ($dropbox_path);
  99. //print_r ($dropbox_path->path);
  100. if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
  101. //print_r("$this->rootPath/$dropbox_path");
  102. return $this->apiCall("media/$this->rootPath/$dropbox_path", "POST");
  103. }
  104. /**
  105. * Download a file to the webserver
  106. *
  107. * @access public
  108. * @param string|object $dropbox_file Dropbox path or metadata object of the file to download.
  109. * @param string $dest_path Local path for destination
  110. * @param int $revision Optional. The revision of the file to retrieve. This defaults to the most recent revision.
  111. * @return object Dropbox file metadata
  112. */
  113. public function DownloadFile($dropbox_file, $dest_path='', $revision=-1)
  114. {
  115. if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
  116. if(empty($dest_path)) $dest_path = basename($dropbox_file);
  117. $url = $this->cleanUrl(self::API_CONTENT_URL."/files/$this->rootPath/$dropbox_file");
  118. $content = ($revision != -1) ? http_build_query(array('rev' => $revision)) : null;
  119. $context = $this->createRequestContext($url, "GET", $content);
  120. $rh = @fopen($url, 'rb', false, $context); // read binary
  121. if($rh === false)
  122. throw new DropboxException("HTTP request to $url failed!");
  123. $fh = @fopen($dest_path, 'wb'); // write binary
  124. if($fh === false) {
  125. @fclose($rh);
  126. throw new DropboxException("Could not create file $dest_path !");
  127. }
  128. $size = 0;
  129. while (!feof($rh)) {
  130. if(($s=fwrite($fh, fread($rh, self::BUFFER_SIZE))) === false) {
  131. @fclose($rh);
  132. @fclose($fh);
  133. throw new DropboxException("Writing to file $dest_path failed!'");
  134. }
  135. $size += $s;
  136. }
  137. // get file meta from HTTP header
  138. $s_meta = stream_get_meta_data($rh);
  139. $meta = json_decode(substr(reset(array_filter($s_meta['wrapper_data'], create_function('$s', 'return strpos($s, "x-dropbox-metadata:") === 0;'))), 20));
  140. fclose($rh);
  141. fclose($fh);
  142. if($meta->bytes != $size)
  143. throw new DropboxException("Download size mismatch!");
  144. return $meta;
  145. }
  146. public function DownloadThumbnail($dropbox_file, $dest_path='', $revision=-1)
  147. {
  148. echo $dropbox_file;
  149. echo $dest_path;
  150. if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
  151. if($dest_path == '')
  152. {
  153. $pieces = explode(".", basename($dropbox_file));
  154. $dest_path = "images/thumbs/Image_$pieces[0].jpeg";
  155. print_r ($dest_path);
  156. }
  157. $url = $this->cleanUrl(self::API_CONTENT_URL."/thumbnails/$this->rootPath/$dropbox_file");
  158. $content = ($revision != -1) ? http_build_query(array('rev' => $revision)) : null;
  159. $context = $this->createRequestContext($url, "GET", $content);
  160. echo "<br>";
  161. echo $url;
  162. $rh = @fopen($url, 'rb', false, $context); // read binary
  163. if($rh === false)
  164. throw new DropboxException("HTTP request to $url failed!");
  165. $fh = @fopen($dest_path, 'wb'); // write binary
  166. if($fh === false) {
  167. @fclose($rh);
  168. throw new DropboxException("Could not create file $dest_path !");
  169. }
  170. $size = 0;
  171. while (!feof($rh)) {
  172. if(($s=fwrite($fh, fread($rh, self::BUFFER_SIZE))) === false) {
  173. @fclose($rh);
  174. @fclose($fh);
  175. throw new DropboxException("Writing to file $dest_path failed!'");
  176. }
  177. $size += $s;
  178. }
  179. // get file meta from HTTP header
  180. $s_meta = stream_get_meta_data($rh);
  181. $meta = json_decode(substr(reset(array_filter($s_meta['wrapper_data'], create_function('$s', 'return strpos($s, "x-dropbox-metadata:") === 0;'))), 20));
  182. fclose($rh);
  183. fclose($fh);
  184. //if($meta->bytes != $size)
  185. //throw new DropboxException("Download size mismatch!");
  186. return $meta;
  187. }
  188. /**
  189. * Upload a file to dropbox
  190. *
  191. * @access public
  192. * @param src_path (String) Local file to upload
  193. * @param dropbox_path (String) Dropbox path for destionation
  194. * @return object Dropbox file metadata
  195. */
  196. public function UploadFile($src_file, $dropbox_path='')
  197. {
  198. if(empty($dropbox_path)) $dropbox_path = basename($src_file);
  199. elseif(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
  200. //$params = array('locale' => $this->locale); //, 'overwrite' => $overwrite ? 'true' : 'false');
  201. //$query = http_build_query($params);
  202. $url = $this->cleanUrl(self::API_CONTENT_URL."/files_put/$this->rootPath/$dropbox_path"); // ?$query TODO causes a 403 forbidden error..
  203. $content =& file_get_contents($src_file);
  204. if(strlen($content) == 0) throw new DropboxException("Could not read file $src_file !");
  205. $context = $this->createRequestContext($url, "PUT", $content);
  206. return json_decode(file_get_contents($url, false, $context));
  207. }
  208. function getFileTree($path="", $max_depth = 0, $depth=0)
  209. {
  210. static $files;
  211. if($depth == 0) $files = array();
  212. $dir = $this->apiCall("metadata/$this->rootPath/$path", "GET");
  213. foreach($dir->contents as $item)
  214. {
  215. $files[trim($item->path,'/')] = $item;
  216. if($item->is_dir && $depth < $max_depth)
  217. {
  218. $this->getFileTree($item->path, $max_depth, $depth+1);
  219. }
  220. }
  221. return $files;
  222. }
  223. function createRequestContext($url, $method, &$content, $oauth_token=-1)
  224. {
  225. if($oauth_token === -1)
  226. $oauth_token = $this->accessToken;
  227. $oauth = new OAuthSimple($this->consumerToken['t'],$this->consumerToken['s']);
  228. $params = array();
  229. if(empty($oauth_token) && !empty($this->accessToken))
  230. $oauth_token = $this->accessToken;
  231. if(!empty($oauth_token)) {
  232. $oauth->signatures(array('oauth_secret'=>$oauth_token['s']));
  233. $params['oauth_token'] = $oauth_token['t'];
  234. }
  235. $signed = $oauth->sign(array(
  236. 'action' => $method,
  237. 'path'=> $url,
  238. 'parameters'=> $params));
  239. $header = "Authorization: ".$signed['header']."\r\n";
  240. //echo "<br><br>SBS: $signed[sbs]<br><br>";
  241. $http_context = array(
  242. 'method'=>$method,
  243. 'header'=> $header);
  244. if(!empty($content)) {
  245. $http_context['header'] .= "Content-Length: ".strlen($content)."\r\n";
  246. $http_context['header'] .= "Content-Type: application/octet-stream\r\n";
  247. $http_context['content'] =& $content;
  248. }
  249. return stream_context_create(array('http'=>$http_context));
  250. }
  251. function authCall($path, $request_token=null)
  252. {
  253. $url = $this->cleanUrl(self::API_URL.$path);
  254. $dummy = null;
  255. $context = $this->createRequestContext($url, "POST", $dummy, $request_token);
  256. $data = array();
  257. parse_str(file_get_contents($url, false, $context), $data);
  258. return $data;
  259. }
  260. function apiCall($path, $method, $params=array())
  261. {
  262. $url = $this->cleanUrl(self::API_URL.$path);
  263. $content = http_build_query(array_merge(array('locale'=>$this->locale), $params));
  264. $context = $this->createRequestContext($url, $method, $content);
  265. return json_decode(file_get_contents($url, false, $context));
  266. }
  267. function cleanUrl($url) {
  268. return substr($url,0,8).str_replace('//','/', str_replace('\\','/',substr($url,8)));
  269. }
  270. }
  271. class DropboxException extends Exception {
  272. public function __construct($err, $isDebug = FALSE)
  273. {
  274. $this->message = $err;
  275. self::log_error($err);
  276. if ($isDebug)
  277. {
  278. self::display_error($err, TRUE);
  279. }
  280. }
  281. public static function log_error($err)
  282. {
  283. error_log($err, 0);
  284. }
  285. public static function display_error($err, $kill = FALSE)
  286. {
  287. print_r($err);
  288. if ($kill === FALSE)
  289. {
  290. die();
  291. }
  292. }
  293. }