Skip to content

Commit

Permalink
Implement copying files
Browse files Browse the repository at this point in the history
The b2 API supports copying files through the endpoint b2_copy_file.

The options array supports BucketName or BucketId, FileName, SaveAs, and
optionally destinationBucketId or destinationBucketName.

As a bonus, there is now getFileIdFromBucketIdAndFileName, a faster
way to retrieve FileIds for single files.
  • Loading branch information
remmelt committed Feb 2, 2021
1 parent c6aa7b9 commit 52c4f65
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ $fileContent = $client->download([
]);
```

#### File Copy
``` php
$copyOfFile = $client->copy([
'BucketName' => $bucketName,
'FileName' => $path,
'SaveAs' => $newPath,

// Can also supply BucketId instead of BucketName
// Optional are DestinationBucketName or DestinationBucketId
]);
```

#### File Delete
``` php
$fileDelete = $client->deleteFile([
Expand Down
59 changes: 59 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,65 @@ public function download(array $options)
return isset($options['SaveAs']) ? true : $response;
}

/**
* Copy a file.
*
* $options:
* required BucketName or BucketId the source bucket
* required FileName the file to copy
* required SaveAs the path and file name to save to
* optional DestinationBucketId or DestinationBucketName, the destination bucket
*
* @param array $options
*
* @throws B2Exception
* @throws GuzzleException
* @throws InvalidArgumentException
*
* @return File
*/
public function copy(array $options)
{
$options['FileName'] = ltrim($options['FileName'], '/');
$options['SaveAs'] = ltrim($options['SaveAs'], '/');

if (!isset($options['DestinationBucketId']) && isset($options['DestinationBucketName'])) {
$options['DestinationBucketId'] = $this->getBucketIdFromName($options['DestinationBucketName']);
}

if (!isset($options['BucketId']) && isset($options['BucketName'])) {
$options['BucketId'] = $this->getBucketIdFromName($options['BucketName']);
}

$sourceFiles = $this->listFiles($options['BucketId'], $options['FileName']);
$sourceFileId = !empty($sourceFiles) ? $sourceFiles[0]->getId() : false;
if (!$sourceFileId) {
throw new InvalidArgumentException('Source file not found in B2');
}

$json = [
'sourceFileId' => $sourceFileId,
'fileName' => $options['SaveAs'],
];
if (isset($options['DestinationBucketId'])) {
$json['DestinationBucketId'] = $options['DestinationBucketId'];
}

$response = $this->sendAuthorizedRequest('POST', 'b2_copy_file', $json);

return new File(
$response['fileId'],
$response['fileName'],
$response['contentSha1'],
$response['contentLength'],
$response['contentType'],
$response['fileInfo'],
$response['bucketId'],
$response['action'],
$response['uploadTimestamp'],
);
}

/**
* Retrieve a collection of File objects representing the files stored inside a bucket.
*
Expand Down
20 changes: 20 additions & 0 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,26 @@ public function testGettingNonExistentFileThrowsException()
]);
}

public function testCopyFile()
{
$guzzle = $this->buildGuzzleFromResponses([
$this->buildResponseFromStub(200, [], 'authorize_account.json'),
$this->buildResponseFromStub(200, [], 'list_files_page1.json'),
$this->buildResponseFromStub(200, [], 'copy_file.json'),
]);

$client = new Client('testId', 'testKey', ['client' => $guzzle]);

$actual = $client->copy([
'BucketId' => 'sourceBucketId',
'FileName' => 'sourceFileName',
'SaveAs' => 'destinationFileName',
]);

$this->assertInstanceOf('BackblazeB2\File', $actual);
$this->assertEquals('4_z4c2b953461da9c825f260e1b_f1114dbf5bg9707e8_d20160206_m012226_c001_v1111017_t0010', $actual->getId());
}

public function testDeleteFile()
{
$guzzle = $this->buildGuzzleFromResponses([
Expand Down
14 changes: 14 additions & 0 deletions tests/responses/copy_file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"accountId": "accountId",
"bucketId": "bucketId",
"contentLength": 20,
"contentSha1": "bc77b0349d325be71ed2ca26d5e68173210e9e18",
"contentType": "application/octet-stream",
"fileId": "4_z4c2b953461da9c825f260e1b_f1114dbf5bg9707e8_d20160206_m012226_c001_v1111017_t0010",
"fileInfo": {
"src_last_modified_millis": "1454721688784"
},
"action": "upload",
"uploadTimestamp": "1465983870000",
"fileName": "Test file.bin"
}
18 changes: 18 additions & 0 deletions tests/responses/list_files_single.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"files": [
{
"accountId": "accountId",
"bucketId": "bucketId",
"contentLength": 20,
"contentSha1": "bc77b0349d325be71ed2ca26d5e68173210e9e18",
"contentType": "application/octet-stream",
"fileId": "4_z4c2b953461da9c825f260e1b_f1114dbf5bg9707e8_d20160206_m012226_c001_v1111017_t0010",
"fileInfo": {
"src_last_modified_millis": "1454721688784"
},
"action": "upload",
"uploadTimestamp": "1465983870000",
"fileName": "Test file.bin"
}
]
}

0 comments on commit 52c4f65

Please sign in to comment.