View source
<?php
define('BACKUP_MIGRATE_DROPBOX_CONTENT_URL', 'https://content.dropboxapi.com/2/files');
class BackupMigrateDropboxAPI {
private $token;
private $upload_session = array();
public function setToken($token) {
$this->token = $token;
}
public function file_upload($file, $path) {
$php_memory_limit = intval(backup_migrate_dropbox_byte_size(ini_get('memory_limit')) * 0.9);
$dropbox_upload_limit = backup_migrate_dropbox_byte_size('150M');
$manual_upload_limit = backup_migrate_dropbox_byte_size(variable_get('backup_migrate_dropbox_upload_limit', '150M'));
$max_file_size = min($php_memory_limit, $dropbox_upload_limit, $manual_upload_limit);
$file_size = filesize($file);
if ($file_size > $max_file_size) {
$file_handle = fopen($file, 'rb');
if (!$file_handle) {
throw new ErrorException('Cannot open backup file (1).');
}
$content = fread($file_handle, $max_file_size);
if (!$content) {
throw new ErrorException('Cannot read backup file (2).');
}
$this
->_file_upload_session_start($content);
while (!feof($file_handle)) {
$content = fread($file_handle, $max_file_size);
if (!$content) {
throw new ErrorException('Cannot read backup file (3).');
}
$this
->_file_upload_session_append($content);
}
$this
->_file_upload_session_finish($path);
}
else {
$content = file_get_contents($file);
if (!$content) {
throw new ErrorException('Cannot open backup file (4).');
}
$this
->_file_upload_upload($path, $content);
}
}
private function _file_upload_session_start($content) {
$header = array();
$header[] = 'Content-type: application/octet-stream';
$header[] = 'Authorization: Bearer ' . $this->token;
$header[] = 'Accept: application/json';
$request = curl_init();
curl_setopt($request, CURLOPT_URL, BACKUP_MIGRATE_DROPBOX_CONTENT_URL . '/upload_session/start');
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $header);
curl_setopt($request, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($request, CURLOPT_POSTFIELDS, $content);
$result = json_decode($this
->_execute_curl($request), TRUE);
if (!is_array($result) || !isset($result['session_id'])) {
throw new ErrorException('No session id returned.');
}
curl_close($request);
$this->upload_session['session_id'] = $result['session_id'];
$this->upload_session['offset'] = strlen($content);
}
private function _file_upload_session_append($content) {
$parameters = array(
'cursor' => $this->upload_session,
);
$header = array();
$header[] = 'Content-type: application/octet-stream';
$header[] = 'Authorization: Bearer ' . $this->token;
$header[] = 'Dropbox-API-Arg: ' . json_encode($parameters);
$header[] = 'Accept: application/json';
$request = curl_init();
curl_setopt($request, CURLOPT_URL, BACKUP_MIGRATE_DROPBOX_CONTENT_URL . '/upload_session/append_v2');
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $header);
curl_setopt($request, CURLOPT_POSTFIELDS, $content);
curl_setopt($request, CURLOPT_RETURNTRANSFER, TRUE);
$this
->_execute_curl($request);
curl_close($request);
$this->upload_session['offset'] += strlen($content);
}
private function _file_upload_session_finish($path) {
$parameters = array(
'cursor' => $this->upload_session,
'commit' => array(
'path' => $path,
'mode' => 'add',
'autorename' => TRUE,
'mute' => TRUE,
),
);
$header = array();
$header[] = 'Content-type: application/octet-stream';
$header[] = 'Authorization: Bearer ' . $this->token;
$header[] = 'Dropbox-API-Arg: ' . json_encode($parameters);
$header[] = 'Accept: application/json';
$request = curl_init();
curl_setopt($request, CURLOPT_URL, BACKUP_MIGRATE_DROPBOX_CONTENT_URL . '/upload_session/finish');
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $header);
curl_setopt($request, CURLOPT_RETURNTRANSFER, TRUE);
$this
->_execute_curl($request);
curl_close($request);
}
private function _file_upload_upload($path, $content) {
$parameters = array(
'path' => $path,
'mode' => 'add',
'autorename' => TRUE,
'mute' => FALSE,
);
$header = array();
$header[] = 'Content-type: application/octet-stream';
$header[] = 'Authorization: Bearer ' . $this->token;
$header[] = 'Dropbox-API-Arg: ' . json_encode($parameters);
$header[] = 'Accept: application/json';
$request = curl_init();
curl_setopt($request, CURLOPT_URL, BACKUP_MIGRATE_DROPBOX_CONTENT_URL . '/upload');
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $header);
curl_setopt($request, CURLOPT_POSTFIELDS, $content);
curl_setopt($request, CURLOPT_RETURNTRANSFER, TRUE);
$this
->_execute_curl($request);
curl_close($request);
}
private function _execute_curl($request) {
$result = curl_exec($request);
$response_code = curl_getinfo($request, CURLINFO_HTTP_CODE);
if (curl_error($request)) {
throw new ErrorException('Curl error: ' . curl_error($request));
}
elseif (isset($result['error'])) {
$result = json_decode($result);
throw new ErrorException('Dropbox error: ' . $result['error_summary']);
}
elseif ($response_code >= 500) {
throw new ErrorException('Dropbox server error. Try later or check status.dropbox.com for outages.');
}
elseif ($response_code >= 400) {
throw new ErrorException('Bad http status response code (' . $response_code . '): ' . $result);
}
return $result;
}
}
function backup_migrate_dropbox_byte_size($byteString) {
preg_match('/^\\s*([0-9.]+)\\s*([KMGT])B?\\s*$/i', $byteString, $matches);
if (!(count($matches) >= 3)) {
return 0;
}
$num = (double) $matches[1];
switch (strtoupper($matches[2])) {
case 'T':
$num *= DRUPAL_KILOBYTE;
case 'G':
$num *= DRUPAL_KILOBYTE;
case 'M':
$num *= DRUPAL_KILOBYTE;
case 'K':
$num *= DRUPAL_KILOBYTE;
}
return intval($num);
}