PageRenderTime 61ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/kz40_site/www/wp/wp-content/plugins/backup-by-supsystic/modules/dropbox/models/dropbox52.php

https://gitlab.com/megathrone86/SoftwareProjects
PHP | 460 lines | 297 code | 86 blank | 77 comment | 41 complexity | f14901cac437b686c1f71122a0e65119 MD5 | raw file
  1. <?php
  2. /**
  3. * Class dropbox52ModelBup
  4. * This class uses only with PHP on 32bit system or with PHP 5.2.x
  5. * @package Dropbox\Models
  6. */
  7. class dropbox52ModelBup extends modelBup {
  8. /**
  9. * Key to store token to the session
  10. */
  11. const TOKEN = 'dropbox_token';
  12. private $_inFile = NULL;
  13. private $_chunkSize = 4194304;
  14. const API_URL = 'https://api.dropbox.com/1/';
  15. const CONTENT_URL = 'https://api-content.dropbox.com/1/';
  16. /**
  17. * Dummy method
  18. * @return bool
  19. */
  20. public function isSupported() { return true; }
  21. /**
  22. * Is authenticated user?
  23. * @return bool
  24. */
  25. public function isAuthenticated() {
  26. if (isset($_SESSION[self::TOKEN]) && !empty($_SESSION[self::TOKEN])) {
  27. return true;
  28. }
  29. if (null !== ($token = $this->readToken())) {
  30. $_SESSION[self::TOKEN] = $token;
  31. return true;
  32. }
  33. return false;
  34. }
  35. /**
  36. * Authenticate user
  37. * @param string $token Dropbox OAuth2 Token from Authenticator
  38. * @return bool
  39. */
  40. public function authenticate($token) {
  41. if (!$this->isSessionStarted()) {
  42. session_start();
  43. }
  44. $_SESSION[self::TOKEN] = $token;
  45. $this->saveToken($token);
  46. return true;
  47. }
  48. /**
  49. * Get an associative array with dropbox metadata from sandbox
  50. * @return array|null
  51. */
  52. public function getUploadedFiles($stacksFolder = '') {
  53. if (!$this->isAuthenticated()) {
  54. return null;
  55. }
  56. $url = self::API_URL. 'metadata/sandbox' . $this->getDropboxPath() . $stacksFolder;
  57. $request = curlBup::createGetRequest($url, array(
  58. 'file_limit' => 25000,
  59. 'list' => 'true',
  60. 'locale' => 'en',
  61. ));
  62. $request->setAuthorization($this->getToken());
  63. // try {
  64. $response = json_decode($request->exec(), true);
  65. // } catch (RuntimeException $e) {
  66. // exit (sprintf('Dropbox Client error: %s\nTry to refresh page', $e->getMessage()));
  67. // }
  68. if (isset($response['error'])) {
  69. return null;
  70. }
  71. // Formatting uploading data files for use their on backups page
  72. $files = array();
  73. if(!$stacksFolder) {
  74. foreach ($response['contents'] as $file) {
  75. $pathInfo = pathinfo($file['path']);
  76. $backupInfo = $this->getBackupInfoByFilename($pathInfo['basename']);
  77. if (!empty($backupInfo['ext']) && $backupInfo['ext'] == 'sql') {
  78. $files[$backupInfo['id']]['dropbox']['sql'] = $file;
  79. $files[$backupInfo['id']]['dropbox']['sql']['backupInfo'] = $backupInfo;
  80. $files[$backupInfo['id']]['dropbox']['sql']['backupInfo'] = dispatcherBup::applyFilters('addInfoIfEncryptedDb', $files[$backupInfo['id']]['dropbox']['sql']['backupInfo']);
  81. } else {
  82. $files[$backupInfo['id']]['dropbox']['zip'] = $file;
  83. $files[$backupInfo['id']]['dropbox']['zip']['backupInfo'] = $backupInfo;
  84. }
  85. }
  86. unset($response['contents']);
  87. $response['contents'] = $files;
  88. } else {
  89. foreach ($response['contents'] as $file) {
  90. $pathInfo = pathinfo($file['path']);
  91. $files[] = basename($pathInfo['dirname']) . '/' . basename($file['path']);
  92. }
  93. $response = $files;
  94. }
  95. return $response;
  96. }
  97. /**
  98. * Trim the path of forward slashes and replace
  99. * consecutive forward slashes with a single slash
  100. * @param string $path The path to normalise
  101. * @return string
  102. */
  103. private function normalisePath($path)
  104. {
  105. $path = preg_replace('#/+#', '/', trim($path, '/'));
  106. return $path;
  107. }
  108. /**
  109. * Encode the path, then replace encoded slashes
  110. * with literal forward slash characters
  111. * @param string $path The path to encode
  112. * @return string
  113. */
  114. private function encodePath($path)
  115. {
  116. $path = $this->normalisePath($path);
  117. $path = str_replace('%2F', '/', rawurlencode($path));
  118. return $path;
  119. }
  120. /**
  121. * Upload files to Dropbox
  122. * @param array $files An array of files to upload
  123. * @return int
  124. */
  125. public function upload($files = array(), $stacksFolder = '') {
  126. if (!$this->isAuthenticated()) return 401;
  127. if (empty($files)) return 404;
  128. $filepath = $this->getBackupsPath();
  129. foreach ($files as $file) {
  130. $file = basename($file);
  131. if (file_exists($file = rtrim($filepath, '/') . '/' . $stacksFolder . $file)) {
  132. $pointer = @fopen($file, 'rb');
  133. if (!$pointer) {
  134. $this->pushError(sprintf('Failed to read file: %s', $file));
  135. return 500;
  136. }
  137. $uid = null;
  138. $chunkSize = 4194304;
  139. $totalSize = 0;
  140. $body = fread($pointer, $chunkSize);
  141. if (!$body) {
  142. $this->pushError(sprintf('Errors while reading file: %s', $file));
  143. return 500;
  144. }
  145. try {
  146. $request = curlBup::createPutRequest(
  147. self::CONTENT_URL . 'chunked_upload',
  148. array(),
  149. $body
  150. );
  151. $request->setAuthorization($this->getToken());
  152. $request->setHeader('Content-Type', 'application/octet-stream');
  153. $response = json_decode($request->exec(), true);
  154. if (!isset($response['upload_id'])) {
  155. $error = 'Failed to retrieve upload id.';
  156. if (isset($response['error'])) {
  157. $error = implode(':', $response);
  158. }
  159. throw new Exception($error);
  160. }
  161. $uid = $response['upload_id'];
  162. $totalSize = $response['offset'];
  163. } catch (Exception $e) {
  164. $this->pushError($e->getMessage());
  165. return 500;
  166. }
  167. while(!feof($pointer)) {
  168. fseek($pointer, $totalSize);
  169. $body = fread($pointer, $chunkSize);
  170. if (!$body) {
  171. $this->pushError(sprintf('Errors while reading file: %s', $file));
  172. return 500;
  173. }
  174. $fields = array(
  175. 'offset' => $totalSize,
  176. 'upload_id' => $uid,
  177. );
  178. try {
  179. $request = curlBup::createPutRequest(
  180. self::CONTENT_URL . 'chunked_upload',
  181. $fields,
  182. $body
  183. );
  184. $request->setHeader('Content-Type', 'application/octet-stream');
  185. $request->setAuthorization($this->getToken());
  186. $response = json_decode($request->exec(), true);
  187. if (isset($response['error'])) {
  188. throw new Exception(implode(':', $response));
  189. }
  190. $uid = $response['upload_id'];
  191. $totalSize = $response['offset'];
  192. } catch (Exception $e) {
  193. $this->pushError($e->getMessage());
  194. return 500;
  195. }
  196. }
  197. fclose($pointer);
  198. try {
  199. $url = self::CONTENT_URL
  200. . 'commit_chunked_upload/auto'
  201. . $this->getDropboxPath()
  202. . $stacksFolder
  203. . basename($file);
  204. $request = curlBup::createPostRequest(
  205. $url,
  206. array(
  207. 'upload_id' => $uid,
  208. 'overwrite' => 1,
  209. )
  210. );
  211. $request->setAuthorization($this->getToken());
  212. $response = json_decode($request->exec(), true);
  213. if (isset($response['error'])) {
  214. throw new Exception(implode(':', $response));
  215. }
  216. } catch (Exception $e) {
  217. $this->pushError($e->getMessage());
  218. return 500;
  219. }
  220. } else {
  221. $this->pushError(sprintf('File not found: %s', $file));
  222. return 404;
  223. }
  224. }
  225. return 200;
  226. }
  227. /**
  228. * Remove file from Dropbox
  229. * @param string $filepath Filename with full path to file
  230. * @return bool
  231. */
  232. public function remove($filepath) {
  233. if (!$this->isAuthenticated()) {
  234. $this->pushError(__('Authentication required', BUP_LANG_CODE));
  235. return false;
  236. }
  237. $url = self::API_URL. 'fileops/delete';
  238. $request = curlBup::createPostRequest($url, array(
  239. 'root' => 'sandbox',
  240. 'path' => $filepath,
  241. 'locale' => 'en',
  242. ));
  243. $request->setAuthorization($this->getToken());
  244. try {
  245. $response = json_decode($request->exec(), true);
  246. } catch (RuntimeException $e) {
  247. $this->pushError($e->getMessage());
  248. return false;
  249. }
  250. if (isset($response['error'])) {
  251. $this->pushError(implode(':', $response));
  252. return false;
  253. }
  254. return true;
  255. }
  256. /**
  257. * Download file from Dropbox
  258. * @param string $filename Name of the file to download
  259. * @return bool
  260. */
  261. public function download($filename, $returnDataString = false) {
  262. @set_time_limit(0);
  263. if (!$this->isAuthenticated()) {
  264. $this->pushError(__('Authentication required', BUP_LANG_CODE));
  265. return false;
  266. }
  267. if (file_exists($this->getBackupsPath() . $filename)) {
  268. return $returnDataString ? file_get_contents($this->getBackupsPath() . $filename) : true;
  269. }
  270. $url = self::CONTENT_URL. 'files/sandbox';
  271. $request = curlBup::createGetRequest(
  272. $url . $this->getDropboxPath() . ltrim($filename, '/')
  273. );
  274. $request->setAuthorization($_SESSION[self::TOKEN]);
  275. try {
  276. $response = $request->exec();
  277. } catch (RuntimeException $e) {
  278. $this->pushError($e->getMessage());
  279. }
  280. if($returnDataString)
  281. return $response;
  282. if (!file_put_contents($this->getBackupsPath() . $filename, $response)) {
  283. $this->pushError(__(sprintf('Can\'t download the file: %', $filename), BUP_LANG_CODE));
  284. return false;
  285. }
  286. return true;
  287. }
  288. /**
  289. * Dummy method
  290. * @return array
  291. */
  292. public function getQuota() {
  293. return array();
  294. }
  295. /**
  296. * Is session already started?
  297. * @return bool
  298. */
  299. public function isSessionStarted() {
  300. if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
  301. return session_status() === PHP_SESSION_NONE ? false : true;
  302. } else {
  303. return session_id() === '' ? false : true;
  304. }
  305. }
  306. /**
  307. * Get path to the backups
  308. * @return string
  309. */
  310. public function getBackupsPath() {
  311. return frameBup::_()->getModule('warehouse')->getPath()
  312. . DIRECTORY_SEPARATOR;
  313. }
  314. public function removeToken()
  315. {
  316. $storage = frameBup::_()->getModule('warehouse')->getPath();
  317. if (false !== $expired = glob($storage . '/dropbox*.json')) {
  318. if (is_array($expired) && count($expired) > 0) {
  319. foreach ($expired as $file) {
  320. @unlink($file);
  321. }
  322. }
  323. }
  324. }
  325. /**
  326. * Saves the token
  327. *
  328. * @param string $token
  329. */
  330. protected function saveToken($token)
  331. {
  332. $storage = frameBup::_()->getModule('warehouse')->getPath();
  333. $this->removeToken();
  334. file_put_contents($storage . '/' . uniqid('dropbox') . '.json', $token);
  335. }
  336. /**
  337. * Reads the token
  338. */
  339. protected function readToken()
  340. {
  341. $storage = frameBup::_()->getModule('warehouse')->getPath();
  342. if (false !== $token = glob($storage . '/dropbox*.json')) {
  343. if (is_array($token) && count($token) === 1) {
  344. return file_get_contents($token[0]);
  345. }
  346. }
  347. return null;
  348. }
  349. protected function getDomainName()
  350. {
  351. return parse_url(get_bloginfo('wpurl'), PHP_URL_HOST);
  352. }
  353. protected function getDropboxPath()
  354. {
  355. return '/' . $this->getDomainName() . '/';
  356. }
  357. protected function getToken()
  358. {
  359. if(isset($_SESSION[self::TOKEN]) && !empty($_SESSION[self::TOKEN])) {
  360. return $_SESSION[self::TOKEN];
  361. }
  362. if (null !== ($token = $this->readToken())) {
  363. return $token;
  364. }
  365. return false;
  366. }
  367. public function isUserAuthorizedInService($destination = null)
  368. {
  369. $isAuthorized = $this->isAuthenticated() ? true : false;
  370. if(!$isAuthorized)
  371. $this->pushError($this->backupPlaceAuthErrorMsg . 'DropBox!');
  372. return $isAuthorized;
  373. }
  374. }