Skip to content

Commit 3a6e1ea

Browse files
committed
feat: add writeBatch operation
1 parent 2cb8fed commit 3a6e1ea

File tree

3 files changed

+79
-63
lines changed

3 files changed

+79
-63
lines changed

src/BunnyCDNAdapter.php

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace PlatformCommunity\Flysystem\BunnyCDN;
44

55
use Exception;
6+
use GuzzleHttp\Exception\RequestException;
7+
use GuzzleHttp\Pool;
68
use League\Flysystem\CalculateChecksumFromStream;
79
use League\Flysystem\ChecksumProvider;
810
use League\Flysystem\Config;
@@ -35,27 +37,8 @@ class BunnyCDNAdapter implements FilesystemAdapter, PublicUrlGenerator, Checksum
3537
{
3638
use CalculateChecksumFromStream;
3739

38-
/**
39-
* Pull Zone URL
40-
*
41-
* @var string
42-
*/
43-
private string $pullzone_url;
44-
45-
/**
46-
* @var BunnyCDNClient
47-
*/
48-
private BunnyCDNClient $client;
49-
50-
/**
51-
* @param BunnyCDNClient $client
52-
* @param string $pullzone_url
53-
*/
54-
public function __construct(BunnyCDNClient $client, string $pullzone_url = '')
40+
public function __construct(private BunnyCDNClient $client, private string $pullzone_url = '')
5541
{
56-
$this->client = $client;
57-
$this->pullzone_url = $pullzone_url;
58-
5942
if (\func_num_args() > 2 && (string) \func_get_arg(2) !== '') {
6043
throw new \RuntimeException('PrefixPath is no longer supported directly. Use PathPrefixedAdapter instead: https://flysystem.thephpleague.com/docs/adapter/path-prefixing/');
6144
}
@@ -70,12 +53,9 @@ public function __construct(BunnyCDNClient $client, string $pullzone_url = '')
7053
public function copy($source, $destination, Config $config): void
7154
{
7255
try {
73-
/** @var array<string> $files */
74-
$files = iterator_to_array($this->getFiles($source));
75-
7656
$sourceLength = \strlen($source);
7757

78-
foreach ($files as $file) {
58+
foreach ($this->getFiles($source) as $file) {
7959
$this->copyFile($file, $destination.\substr($file, $sourceLength), $config);
8060
}
8161
} catch (UnableToReadFile|UnableToWriteFile $exception) {
@@ -225,6 +205,34 @@ public function writeStream($path, $contents, Config $config): void
225205
$this->write($path, stream_get_contents($contents), $config);
226206
}
227207

208+
/**
209+
* @param WriteBatchFile[] $writeBatches
210+
* @param Config $config
211+
* @return void
212+
*/
213+
public function writeBatch(array $writeBatches, Config $config): void
214+
{
215+
$concurrency = (int) $config->get('concurrency', 50);
216+
217+
foreach (\array_chunk($writeBatches, $concurrency) as $batch) {
218+
$requests = function () use ($batch) {
219+
/** @var WriteBatchFile $file */
220+
foreach ($batch as $file) {
221+
yield $this->client->getUploadRequest($file->targetPath, \file_get_contents($file->localPath));
222+
}
223+
};
224+
225+
$pool = new Pool($this->client->client, $requests(), [
226+
'concurrency' => $concurrency,
227+
'rejected' => function (RequestException $reason, int $index) {
228+
throw UnableToWriteFile::atLocation($index, $reason->getMessage());
229+
},
230+
]);
231+
232+
$pool->promise()->wait();
233+
}
234+
}
235+
228236
/**
229237
* @param $path
230238
* @return resource

src/BunnyCDNClient.php

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,13 @@
1111

1212
class BunnyCDNClient
1313
{
14-
public string $storage_zone_name;
15-
16-
private string $api_key;
17-
18-
private string $region;
19-
2014
public Guzzle $client;
2115

22-
public function __construct(string $storage_zone_name, string $api_key, string $region = BunnyCDNRegion::FALKENSTEIN)
23-
{
24-
$this->storage_zone_name = $storage_zone_name;
25-
$this->api_key = $api_key;
26-
$this->region = $region;
27-
16+
public function __construct(
17+
public string $storage_zone_name,
18+
private string $api_key,
19+
private string $region = BunnyCDNRegion::FALKENSTEIN
20+
) {
2821
$this->client = new Guzzle();
2922
}
3023

@@ -43,27 +36,25 @@ private static function get_base_url($region): string
4336
};
4437
}
4538

46-
public function createRequest(string $path, string $method = 'GET', array $options = []): Request
39+
public function createRequest(string $path, string $method = 'GET', array $headers = [], $body = null): Request
4740
{
48-
return new Request($method,
41+
return new Request(
42+
$method,
4943
self::get_base_url($this->region).Util::normalizePath('/'.$this->storage_zone_name.'/').$path,
50-
array_merge_recursive([
51-
'headers' => [
52-
'Accept' => '*/*',
53-
'AccessKey' => $this->api_key, // Honestly... Why do I have to specify this twice... @BunnyCDN
54-
],
55-
], $options)
44+
array_merge([
45+
'Accept' => '*/*',
46+
'AccessKey' => $this->api_key,
47+
], $headers),
48+
$body
5649
);
5750
}
5851

5952
/**
6053
* @throws ClientExceptionInterface
6154
*/
62-
private function request(string $path, string $method = 'GET', array $options = []): mixed
55+
private function request(Request $request, array $options = []): mixed
6356
{
64-
$request = $this->createRequest($path, $method, $options);
65-
66-
$contents = $this->client->sendRequest($request)->getBody()->getContents();
57+
$contents = $this->client->send($request, $options)->getBody()->getContents();
6758

6859
return json_decode($contents, true) ?? $contents;
6960
}
@@ -77,7 +68,7 @@ private function request(string $path, string $method = 'GET', array $options =
7768
public function list(string $path): array
7869
{
7970
try {
80-
$listing = $this->request(Util::normalizePath($path).'/');
71+
$listing = $this->request($this->createRequest(Util::normalizePath($path).'/'));
8172

8273
// Throw an exception if we don't get back an array
8374
if (! is_array($listing)) {
@@ -107,7 +98,7 @@ public function list(string $path): array
10798
public function download(string $path): string
10899
{
109100
try {
110-
$content = $this->request($path.'?download');
101+
$content = $this->request($this->createRequest($path.'?download'));
111102

112103
if (\is_array($content)) {
113104
return \json_encode($content);
@@ -134,7 +125,7 @@ public function download(string $path): string
134125
public function stream(string $path)
135126
{
136127
try {
137-
return $this->createRequest($path, 'GET', ['stream' => true])->getBody()->detach();
128+
return $this->request($this->createRequest($path), ['stream' => true])->getBody()->detach();
138129
// @codeCoverageIgnoreStart
139130
} catch (GuzzleException $e) {
140131
throw match ($e->getCode()) {
@@ -145,6 +136,18 @@ public function stream(string $path)
145136
// @codeCoverageIgnoreEnd
146137
}
147138

139+
public function getUploadRequest(string $path, $contents): Request
140+
{
141+
return $this->createRequest(
142+
$path,
143+
'PUT',
144+
[
145+
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
146+
],
147+
$contents
148+
);
149+
}
150+
148151
/**
149152
* @param string $path
150153
* @param $contents
@@ -155,12 +158,7 @@ public function stream(string $path)
155158
public function upload(string $path, $contents): mixed
156159
{
157160
try {
158-
return $this->request($path, 'PUT', [
159-
'headers' => [
160-
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
161-
],
162-
'body' => $contents,
163-
]);
161+
return $this->request($this->getUploadRequest($path, $contents));
164162
// @codeCoverageIgnoreStart
165163
} catch (GuzzleException $e) {
166164
throw new BunnyCDNException($e->getMessage());
@@ -177,11 +175,9 @@ public function upload(string $path, $contents): mixed
177175
public function make_directory(string $path): mixed
178176
{
179177
try {
180-
return $this->request(Util::normalizePath($path).'/', 'PUT', [
181-
'headers' => [
182-
'Content-Length' => 0,
183-
],
184-
]);
178+
return $this->request($this->createRequest(Util::normalizePath($path).'/', 'PUT', [
179+
'Content-Length' => 0,
180+
]));
185181
// @codeCoverageIgnoreStart
186182
} catch (GuzzleException $e) {
187183
throw match ($e->getCode()) {
@@ -202,7 +198,7 @@ public function make_directory(string $path): mixed
202198
public function delete(string $path): mixed
203199
{
204200
try {
205-
return $this->request($path, 'DELETE');
201+
return $this->request($this->createRequest($path, 'DELETE'));
206202
// @codeCoverageIgnoreStart
207203
} catch (GuzzleException $e) {
208204
throw match ($e->getCode()) {

src/WriteBatchFile.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace PlatformCommunity\Flysystem\BunnyCDN;
4+
5+
class WriteBatchFile
6+
{
7+
public function __construct(
8+
public string $localPath,
9+
public string $targetPath,
10+
) {
11+
}
12+
}

0 commit comments

Comments
 (0)