first commit
This commit is contained in:
901
wp-content/plugins/updraftplus/includes/Backblaze/CurlClient.php
Normal file
901
wp-content/plugins/updraftplus/includes/Backblaze/CurlClient.php
Normal file
@@ -0,0 +1,901 @@
|
||||
<?php
|
||||
// @codingStandardsIgnoreFile
|
||||
|
||||
if (!defined('UPDRAFTPLUS_DIR')) die('No direct access allowed');
|
||||
|
||||
class UpdraftPlus_Backblaze_CurlClient {
|
||||
|
||||
protected $accountId;
|
||||
protected $applicationKey;
|
||||
protected $credentials;
|
||||
|
||||
protected $authToken;
|
||||
protected $apiUrl;
|
||||
protected $downloadUrl;
|
||||
|
||||
// Whether to verify the server certificate or not
|
||||
protected $sslVerify = true;
|
||||
|
||||
// If set to a string, then it indicates a path for a CA store to use
|
||||
protected $useCACerts = false;
|
||||
|
||||
protected $singleBucketKeyId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param String $accountId
|
||||
* @param String $applicationKey
|
||||
* @param String $singleBucketKeyId
|
||||
* @param Array $options
|
||||
*/
|
||||
public function __construct($accountId, $applicationKey, $singleBucketKeyId = '', array $options = array()) {
|
||||
$this->accountId = $accountId;
|
||||
$this->applicationKey = $applicationKey;
|
||||
$this->singleBucketKeyId = $singleBucketKeyId;
|
||||
if (isset($options['ssl_verify'])) $this->sslVerify = $options['ssl_verify'];
|
||||
if (isset($options['ssl_ca_certs'])) $this->useCACerts = $options['ssl_ca_certs'];
|
||||
$this->authorizeAccount();
|
||||
}
|
||||
|
||||
protected function request($method = 'GET', $uri = '', array $options = array(), $as_json = true) {
|
||||
$session = curl_init($uri);
|
||||
|
||||
$headers = array();
|
||||
|
||||
if (isset($options['auth'])) {
|
||||
$account_id = empty($this->singleBucketKeyId) ? $this->accountId : $this->singleBucketKeyId;
|
||||
$headers[] = 'Authorization: Basic ' . base64_encode($account_id . ':' . $this->applicationKey);
|
||||
}
|
||||
|
||||
if (isset($options['headers'])) {
|
||||
foreach ($options['headers'] as $key => $header) {
|
||||
$headers[] = $key . ': ' . $header;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->sslVerify) {
|
||||
curl_setopt($session, CURLOPT_SSL_VERIFYPEER, true);
|
||||
curl_setopt($session, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
} else {
|
||||
curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($session, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
if ($this->useCACerts) {
|
||||
curl_setopt($session, CURLOPT_CAINFO, $this->useCACerts);
|
||||
}
|
||||
|
||||
if ('GET' == $method) {
|
||||
|
||||
curl_setopt($session, CURLOPT_HTTPGET, true);
|
||||
|
||||
} else {
|
||||
|
||||
$data = array();
|
||||
|
||||
if (isset($options['json'])) {
|
||||
|
||||
$headers[] = "Accept: application/json";
|
||||
$data = json_encode($options['json']);
|
||||
|
||||
}
|
||||
|
||||
if (isset($options['body'])) {
|
||||
|
||||
$data = $options['body'];
|
||||
|
||||
}
|
||||
|
||||
curl_setopt($session, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($session, CURLOPT_POST, true);
|
||||
}
|
||||
|
||||
curl_setopt($session, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
if (isset($options['sink'])) {
|
||||
$sink = fopen($options['sink'], 'w+');
|
||||
curl_setopt($session, CURLOPT_FILE, $sink);
|
||||
curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
|
||||
}
|
||||
|
||||
if (isset($options['session'])) {
|
||||
return $session;
|
||||
}
|
||||
|
||||
$response = curl_exec($session);
|
||||
|
||||
if (0 != ($curl_error = curl_errno($session))) {
|
||||
throw new Exception("Curl error ($curl_error): ".curl_error($session), $curl_error);
|
||||
}
|
||||
|
||||
$decode_response = json_decode($response, true);
|
||||
|
||||
if (isset($decode_response['status']) && 200 !== $decode_response['status']) {
|
||||
|
||||
throw new Exception($decode_response['message'], $decode_response['status']);
|
||||
|
||||
}
|
||||
|
||||
curl_close($session);
|
||||
|
||||
if (!empty($sink)) @fclose($sink);
|
||||
|
||||
if ($as_json) return $decode_response;
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function uploadLargeStart($options) {
|
||||
// Request body parameters
|
||||
if ('/' === substr($options['FileName'], 0, 1)) {
|
||||
$options['FileName'] = ltrim($options['FileName'], '/');
|
||||
}
|
||||
|
||||
if (!isset($options['BucketId']) && isset($options['BucketName'])) {
|
||||
$options['BucketId'] = $this->getBucketIdFromName($options['BucketName']);
|
||||
}
|
||||
|
||||
if (!isset($options['FileContentType'])) {
|
||||
$options['FileContentType'] = 'b2/x-auto';
|
||||
}
|
||||
|
||||
// Request start large file upload
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_start_large_file', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'bucketId' => $options['BucketId'],
|
||||
'fileName' => $options['FileName'],
|
||||
'contentType' => $options['FileContentType'],
|
||||
),
|
||||
));
|
||||
|
||||
/*
|
||||
* fileId
|
||||
* fileName
|
||||
* accountId
|
||||
* bucketId
|
||||
* contentType
|
||||
* fileInfo
|
||||
* uploadTimestamp
|
||||
*/
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function uploadLargeUrl($options) {
|
||||
if (!isset($options['FileId'])) {
|
||||
throw new Exception('FileId required');
|
||||
}
|
||||
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_get_upload_part_url', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'fileId' => $options['FileId'],
|
||||
),
|
||||
));
|
||||
|
||||
/*
|
||||
* authorizationToken
|
||||
* fileId
|
||||
* uploadUrl
|
||||
*/
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function uploadLargePart($options) {
|
||||
|
||||
if (!isset($options['AuthorizationToken'])) {
|
||||
throw new Exception('AuthorizationToken required');
|
||||
}
|
||||
|
||||
if (!isset($options['FilePartNo'])) {
|
||||
throw new Exception('FilePartNo required');
|
||||
}
|
||||
|
||||
if (!isset($options['UploadUrl'])) {
|
||||
throw new Exception('UploadUrl required');
|
||||
}
|
||||
|
||||
if (!isset($options['Body'])) {
|
||||
throw new Exception('Body required');
|
||||
}
|
||||
|
||||
if (is_resource($options['Body'])) {
|
||||
// We need to calculate the file's hash incrementally from the stream.
|
||||
$context = hash_init('sha1');
|
||||
hash_update_stream($context, $options['Body']);
|
||||
$hash = hash_final($context);
|
||||
|
||||
// Similarly, we have to use fstat to get the size of the stream.
|
||||
$fstat = fstat($options['Body']);
|
||||
$size = $fstat['size'];
|
||||
|
||||
// Rewind the stream before passing it to the HTTP client.
|
||||
rewind($options['Body']);
|
||||
} else {
|
||||
// We've been given a simple string body, it's super simple to calculate the hash and size.
|
||||
$hash = sha1($options['Body']);
|
||||
$size = mb_strlen($options['Body'], '8bit');
|
||||
}
|
||||
|
||||
$response = $this->request('POST', $options['UploadUrl'], array(
|
||||
'headers' => array(
|
||||
'Authorization' => $options['AuthorizationToken'],
|
||||
'X-Bz-Part-Number' => $options['FilePartNo'],
|
||||
'Content-Length' => $size,
|
||||
'X-Bz-Content-Sha1' => $hash,
|
||||
),
|
||||
'body' => $options['Body'],
|
||||
));
|
||||
|
||||
/*
|
||||
* fileId
|
||||
* partNumber
|
||||
* contentLength
|
||||
* contentSha1
|
||||
*/
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function uploadLargeFinish($options) {
|
||||
|
||||
if (!isset($options['FileId'])) {
|
||||
throw new Exception('FileId required');
|
||||
}
|
||||
|
||||
if (!isset($options['FilePartSha1Array'])) {
|
||||
throw new Exception('FilePartSha1Array required');
|
||||
}
|
||||
|
||||
if (!is_array($options['FilePartSha1Array'])) {
|
||||
throw new Exception("FilePartSha1Array must be an array");
|
||||
|
||||
}
|
||||
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_finish_large_file', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'fileId' => (string) $options['FileId'],
|
||||
'partSha1Array' => $options['FilePartSha1Array'],
|
||||
),
|
||||
));
|
||||
|
||||
if (empty($response['contentLength'])) {
|
||||
throw new Exception('B2: uploadLargeFinish error: contentLength returned was empty ('.serialize($response).')');
|
||||
}
|
||||
|
||||
return new UpdraftPlus_Backblaze_File(
|
||||
$response['fileId'],
|
||||
$response['fileName'],
|
||||
$response['contentSha1'],
|
||||
$response['contentLength'],
|
||||
$response['contentType'],
|
||||
$response['fileInfo']
|
||||
);
|
||||
}
|
||||
|
||||
protected function authorizeAccount() {
|
||||
$response = $this->request("GET", 'https://api.backblazeb2.com/b2api/v1/b2_authorize_account', array(
|
||||
'auth' => array($this->accountId, $this->applicationKey),
|
||||
));
|
||||
|
||||
$this->authToken = $response['authorizationToken'];
|
||||
$this->apiUrl = $response['apiUrl'] . '/b2api/v1';
|
||||
$this->downloadUrl = $response['downloadUrl'];
|
||||
}
|
||||
|
||||
public function listBuckets() {
|
||||
$buckets = array();
|
||||
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_list_buckets', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'accountId' => $this->accountId,
|
||||
),
|
||||
));
|
||||
|
||||
if (!isset($response['buckets'])) throw new Exception('Failed to list buckets: '.serialize($response));
|
||||
|
||||
foreach ($response['buckets'] as $bucket) {
|
||||
$is_file_lock_enabled = isset($bucket['fileLockConfiguration']['value']['isFileLockEnabled']) ? $bucket['fileLockConfiguration']['value']['isFileLockEnabled'] : false;
|
||||
$buckets[] = new UpdraftPlus_Backblaze_Bucket($bucket['bucketId'], $bucket['bucketName'], $bucket['bucketType'], $is_file_lock_enabled);
|
||||
}
|
||||
|
||||
|
||||
return $buckets;
|
||||
}
|
||||
|
||||
protected function getBucketIdFromName($name) {
|
||||
$buckets = $this->listBuckets();
|
||||
$name = strtolower($name);
|
||||
|
||||
foreach ($buckets as $bucket) {
|
||||
if ($bucket->getName() === $name) {
|
||||
return $bucket->getId();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function getBucketNameFromId($id) {
|
||||
$buckets = $this->listBuckets();
|
||||
|
||||
foreach ($buckets as $bucket) {
|
||||
if ($bucket->getId() === $id) {
|
||||
return $bucket->getName();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function getFileIdFromBucketAndFileName($bucketName, $fileName) {
|
||||
$files = $this->listFiles(array(
|
||||
'BucketName' => $bucketName,
|
||||
'FileName' => $fileName,
|
||||
));
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ($file->getName() === $fileName) {
|
||||
return $file->getId();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function listFiles($options) {
|
||||
// if FileName is set, we only attempt to retrieve information about that single file.
|
||||
$fileName = !empty($options['FileName']) ? $options['FileName'] : null;
|
||||
|
||||
$nextFileName = null;
|
||||
$maxFileCount = 1000;
|
||||
$files = array();
|
||||
|
||||
if (!isset($options['BucketId']) && isset($options['BucketName'])) {
|
||||
$options['BucketId'] = $this->getBucketIdFromName($options['BucketName']);
|
||||
}
|
||||
|
||||
if ($fileName) {
|
||||
$nextFileName = $fileName;
|
||||
$maxFileCount = 1;
|
||||
}
|
||||
|
||||
$json = array(
|
||||
'bucketId' => $options['BucketId'],
|
||||
'startFileName' => $nextFileName,
|
||||
'maxFileCount' => $maxFileCount,
|
||||
);
|
||||
|
||||
if (!empty($options['Prefix'])) $json['prefix'] = $options['Prefix'];
|
||||
|
||||
// B2 returns, at most, 1000 files per "page". Loop through the pages and compile an array of File objects.
|
||||
while (true) {
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_list_file_names', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => $json
|
||||
));
|
||||
|
||||
if (!isset($response['files'])) throw new Exception('Failed to list files. '.serialize($files));
|
||||
|
||||
foreach ($response['files'] as $file) {
|
||||
// if we have a file name set, only retrieve information if the file name matches
|
||||
if (!$fileName || ($fileName === $file['fileName'])) {
|
||||
$files[] = new UpdraftPlus_Backblaze_File($file['fileId'], $file['fileName'], null, $file['size']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($fileName || $response['nextFileName'] === null) {
|
||||
// We've got all the files - break out of loop.
|
||||
break;
|
||||
}
|
||||
|
||||
$json['startFileName'] = $response['nextFileName'];
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function upload($options) {
|
||||
// Clean the path if it starts with /.
|
||||
if (substr($options['FileName'], 0, 1) === '/') {
|
||||
$options['FileName'] = ltrim($options['FileName'], '/');
|
||||
}
|
||||
|
||||
if (!isset($options['BucketId']) && isset($options['BucketName'])) {
|
||||
$options['BucketId'] = $this->getBucketIdFromName($options['BucketName']);
|
||||
}
|
||||
|
||||
// Retrieve the URL that we should be uploading to.
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_get_upload_url', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'bucketId' => $options['BucketId'],
|
||||
),
|
||||
));
|
||||
|
||||
$uploadEndpoint = $response['uploadUrl'];
|
||||
$uploadAuthToken = $response['authorizationToken'];
|
||||
|
||||
if (is_resource($options['Body'])) {
|
||||
// We need to calculate the file's hash incrementally from the stream.
|
||||
$context = hash_init('sha1');
|
||||
hash_update_stream($context, $options['Body']);
|
||||
$hash = hash_final($context);
|
||||
|
||||
// Similarly, we have to use fstat to get the size of the stream.
|
||||
$fstat = fstat($options['Body']);
|
||||
$size = $fstat['size'];
|
||||
|
||||
// Rewind the stream before passing it to the HTTP client.
|
||||
rewind($options['Body']);
|
||||
} else {
|
||||
// We've been given a simple string body, it's super simple to calculate the hash and size.
|
||||
$hash = sha1($options['Body']);
|
||||
$size = mb_strlen($options['Body'], '8bit');
|
||||
}
|
||||
|
||||
if (!isset($options['FileLastModified'])) {
|
||||
$options['FileLastModified'] = round(microtime(true) * 1000);
|
||||
}
|
||||
|
||||
if (!isset($options['FileContentType'])) {
|
||||
$options['FileContentType'] = 'b2/x-auto';
|
||||
}
|
||||
|
||||
$response = $this->request('POST', $uploadEndpoint, array(
|
||||
'headers' => array(
|
||||
'Authorization' => $uploadAuthToken,
|
||||
'Content-Type' => $options['FileContentType'],
|
||||
'Content-Length' => $size,
|
||||
'X-Bz-File-Name' => $options['FileName'],
|
||||
'X-Bz-Content-Sha1' => $hash,
|
||||
'X-Bz-Info-src_last_modified_millis' => $options['FileLastModified'],
|
||||
),
|
||||
'body' => $options['Body'],
|
||||
));
|
||||
|
||||
return new UpdraftPlus_Backblaze_File(
|
||||
$response['fileId'],
|
||||
$response['fileName'],
|
||||
$response['contentSha1'],
|
||||
$response['contentLength'],
|
||||
$response['contentType'],
|
||||
$response['fileInfo']
|
||||
);
|
||||
}
|
||||
|
||||
public function download($options) {
|
||||
$requestUrl = null;
|
||||
$requestOptions = array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'sink' => isset($options['SaveAs']) ? $options['SaveAs'] : null,
|
||||
);
|
||||
|
||||
if (isset($options['FileId'])) {
|
||||
$requestOptions['query'] = array('fileId' => $options['FileId']);
|
||||
$requestUrl = $this->downloadUrl . '/b2api/v1/b2_download_file_by_id';
|
||||
} else {
|
||||
if (!isset($options['BucketName']) && isset($options['BucketId'])) {
|
||||
$options['BucketName'] = $this->getBucketNameFromId($options['BucketId']);
|
||||
}
|
||||
|
||||
$requestUrl = sprintf('%s/file/%s/%s', $this->downloadUrl, $options['BucketName'], $options['FileName']);
|
||||
}
|
||||
|
||||
if (isset($options['headers'])) {
|
||||
$requestOptions['headers'] = array_merge($requestOptions['headers'], $options['headers']);
|
||||
}
|
||||
|
||||
$response = $this->request('GET', $requestUrl, $requestOptions, false);
|
||||
|
||||
return isset($options['SaveAs']) ? true : $response;
|
||||
}
|
||||
|
||||
public function getFile($options) {
|
||||
if (!isset($options['FileId']) && isset($options['BucketName']) && isset($options['FileName'])) {
|
||||
$options['FileId'] = $this->getFileIdFromBucketAndFileName($options['BucketName'], $options['FileName']);
|
||||
|
||||
if (!$options['FileId']) {
|
||||
throw new UpdraftPlus_Backblaze_NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->request('POST', $this->apiUrl . '/b2_get_file_info', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'fileId' => $options['FileId'],
|
||||
),
|
||||
));
|
||||
|
||||
return new UpdraftPlus_Backblaze_File(
|
||||
$response['fileId'],
|
||||
$response['fileName'],
|
||||
$response['contentSha1'],
|
||||
$response['contentLength'],
|
||||
$response['contentType'],
|
||||
$response['fileInfo'],
|
||||
$response['bucketId'],
|
||||
$response['action'],
|
||||
$response['uploadTimestamp']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file
|
||||
*
|
||||
* @param Array $options - possible keys are FileName, FileId, BucketName
|
||||
*
|
||||
* @return Boolean. Can also throw an exception; including UpdraftPlus_Backblaze_NotFoundException if the file was not found.
|
||||
*/
|
||||
public function deleteFile($options) {
|
||||
if (!isset($options['FileName'])) {
|
||||
$file = $this->getFile($options);
|
||||
|
||||
$options['FileName'] = $file->getName();
|
||||
}
|
||||
|
||||
if (!isset($options['FileId']) && isset($options['BucketName']) && isset($options['FileName'])) {
|
||||
$file = $this->getFile($options);
|
||||
|
||||
$options['FileId'] = $file->getId();
|
||||
}
|
||||
|
||||
$delete_result = $this->request('POST', $this->apiUrl . '/b2_delete_file_version', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'fileName' => $options['FileName'],
|
||||
'fileId' => $options['FileId'],
|
||||
),
|
||||
));
|
||||
|
||||
return (is_array($delete_result) && !empty($delete_result['fileId'])) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple files
|
||||
*
|
||||
* @param Array $files_to_delete - array of possible files to delete; sub-keys are FileName, FileId, BucketName
|
||||
* @param String $bucket_name - the bucket that files are being deleted from
|
||||
* @param String|Null - path prefix (to prevent unnecessary scanning of other paths)
|
||||
*
|
||||
* @return Array|Boolean
|
||||
*/
|
||||
public function deleteMultipleFiles($files_to_delete, $bucket_name, $path_prefix = null) {
|
||||
if (count($files_to_delete) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$active = null;
|
||||
$sessions = [];
|
||||
$result = [];
|
||||
$bulk_session = curl_multi_init();
|
||||
|
||||
$list_options = array(
|
||||
'BucketName' => $bucket_name
|
||||
);
|
||||
|
||||
if (is_string($path_prefix) && '' !== $path_prefix) $list_options['Prefix'] = $path_prefix;
|
||||
|
||||
$files = $this->listFiles($list_options);
|
||||
|
||||
$files_lookup = array();
|
||||
|
||||
foreach ($files as $file_object) {
|
||||
$file_name = $file_object->getName();
|
||||
$file_id = $file_object->getId();
|
||||
$files_lookup[$file_name] = $file_id;
|
||||
}
|
||||
|
||||
foreach ($files_to_delete as $file_identification) {
|
||||
|
||||
try {
|
||||
if (!isset($file_identification['FileName'])) {
|
||||
// We should not enter here as we always pass a file name but just in case
|
||||
$file = $this->getFile($file_identification);
|
||||
$file_identification['FileName'] = $file->getName();
|
||||
$file_identification['FileId'] = $file->getId();
|
||||
} elseif (!isset($file_identification['FileId'])) {
|
||||
if (isset($files_lookup[$file_identification['FileName']])) {
|
||||
$file_identification['FileId'] = $files_lookup[$file_identification['FileName']];
|
||||
} else {
|
||||
// We should not enter here as all the files should be in the same bucket but just in case
|
||||
$file = $this->getFile($file_identification);
|
||||
$file_identification['FileId'] = $file->getId();
|
||||
}
|
||||
}
|
||||
} catch (UpdraftPlus_Backblaze_NotFoundException $e) {
|
||||
array_push($sessions, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
$session = $this->request('POST', $this->apiUrl . '/b2_delete_file_version', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'fileName' => $file_identification['FileName'],
|
||||
'fileId' => $file_identification['FileId'],
|
||||
),
|
||||
'session' => true
|
||||
));
|
||||
array_push($sessions, $session);
|
||||
curl_multi_add_handle($bulk_session, $session);
|
||||
}
|
||||
|
||||
do {
|
||||
$status = curl_multi_exec($bulk_session, $active);
|
||||
if ($active) {
|
||||
curl_multi_select($bulk_session);
|
||||
}
|
||||
} while ($active && $status == CURLM_OK);
|
||||
|
||||
foreach ($sessions as $session) {
|
||||
if (is_bool($session)) {
|
||||
array_push($result, $session);
|
||||
continue;
|
||||
}
|
||||
$response = curl_multi_getcontent($session);
|
||||
array_push($result, $response);
|
||||
curl_multi_remove_handle($bulk_session, $session);
|
||||
}
|
||||
curl_multi_close($bulk_session);
|
||||
|
||||
return (is_array($result) && !empty($result)) ? $result : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a private bucket with the given name.
|
||||
*
|
||||
* @param String $bucket_name - valid bucket name
|
||||
* @throws Exception
|
||||
*
|
||||
* @return boolean - If bucket created successfully, it returns true otherwise false.
|
||||
*/
|
||||
public function createPrivateBucket($bucket_name) {
|
||||
try {
|
||||
$response = $this->request('POST', $this->apiUrl.'/b2_create_bucket',
|
||||
array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'accountId' => $this->accountId,
|
||||
'bucketName' => $bucket_name,
|
||||
'bucketType' => 'allPrivate'
|
||||
)
|
||||
)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
if (400 == $e->getCode()) {
|
||||
throw new Exception("Bucket can't be created because Bucket name is already in use.", $e->getCode());
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (isset($response['bucketId']) && isset($response['bucketName']) && isset($response['bucketType'])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object lock for a file in a B2 storage bucket.
|
||||
*
|
||||
* @param string $id The ID of the file to set object lock for.
|
||||
* @param string $filename The name of the file.
|
||||
* @param int $object_lock_duration The duration (in days) for which to set object lock.
|
||||
*
|
||||
* @return array $response The array of response.
|
||||
*/
|
||||
public function setObjectLock($id, $filename, $object_lock_duration) {
|
||||
// Calculate the retain until timestamp (milliseconds) based on the $object_lock_duration.
|
||||
$retain_until_timestamp = (time() + ($object_lock_duration * 86400)) * 1000;
|
||||
|
||||
// Make a request to the B2 API to update file retention settings.
|
||||
$response = $this->request('POST', $this->apiUrl.'/b2_update_file_retention', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'fileId' => $id,
|
||||
'fileName' => $filename,
|
||||
'fileRetention' => array(
|
||||
'mode' => 'compliance',
|
||||
'retainUntilTimestamp' => $retain_until_timestamp
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object lock for a B2 storage bucket.
|
||||
*
|
||||
* @param string $id The ID of the bucket to set object lock for.
|
||||
*
|
||||
* @return array $response The array of response.
|
||||
*/
|
||||
public function setObjectLockToBucket($id) {
|
||||
// Make a request to the B2 API to update file retention settings.
|
||||
$response = $this->request('POST', $this->apiUrl.'/b2_update_bucket', array(
|
||||
'headers' => array(
|
||||
'Authorization' => $this->authToken,
|
||||
),
|
||||
'json' => array(
|
||||
'accountId' => $this->accountId,
|
||||
'bucketId' => $id,
|
||||
'fileLockEnabled' => true
|
||||
)
|
||||
));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final class UpdraftPlus_Backblaze_Bucket {
|
||||
const TYPE_PUBLIC = 'allPublic';
|
||||
const TYPE_PRIVATE = 'allPrivate';
|
||||
|
||||
protected $id;
|
||||
protected $name;
|
||||
protected $type;
|
||||
protected $objectLockEnabled;
|
||||
|
||||
/**
|
||||
* Bucket constructor.
|
||||
*
|
||||
* @param $id
|
||||
* @param $name
|
||||
* @param $type
|
||||
*/
|
||||
public function __construct($id, $name, $type, $objectLockEnabled) {
|
||||
$this->id = $id;
|
||||
$this->name = strtolower($name);
|
||||
$this->type = $type;
|
||||
$this->objectLockEnabled = $objectLockEnabled;
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function isObjectLockEnabled() {
|
||||
return $this->objectLockEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
final class UpdraftPlus_Backblaze_File {
|
||||
protected $id;
|
||||
protected $name;
|
||||
protected $hash;
|
||||
protected $size;
|
||||
protected $type;
|
||||
protected $info;
|
||||
protected $bucketId;
|
||||
protected $action;
|
||||
protected $uploadTimestamp;
|
||||
|
||||
/**
|
||||
* File constructor.
|
||||
*
|
||||
* @param $id
|
||||
* @param $name
|
||||
* @param $hash
|
||||
* @param $size
|
||||
* @param $type
|
||||
* @param $info
|
||||
* @param $bucketId
|
||||
* @param $action
|
||||
* @param $uploadTimestamp
|
||||
*/
|
||||
public function __construct($id, $name, $hash = null, $size = null, $type = null, $info = null, $bucketId = null, $action = null, $uploadTimestamp = null) {
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->hash = $hash;
|
||||
$this->size = $size;
|
||||
$this->type = $type;
|
||||
$this->info = $info;
|
||||
$this->bucketId = $bucketId;
|
||||
$this->action = $action;
|
||||
$this->uploadTimestamp = $uploadTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHash() {
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSize() {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBucketId() {
|
||||
return $this->bucketId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAction() {
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUploadTimestamp() {
|
||||
return $this->uploadTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
class UpdraftPlus_Backblaze_NotFoundException extends Exception {
|
||||
}
|
||||
Reference in New Issue
Block a user