Skip to content

Commit

Permalink
feat: add writeBatch operation
Browse files Browse the repository at this point in the history
  • Loading branch information
tinect committed Oct 21, 2024
1 parent 2cb8fed commit 3a6e1ea
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 63 deletions.
56 changes: 32 additions & 24 deletions src/BunnyCDNAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace PlatformCommunity\Flysystem\BunnyCDN;

use Exception;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use League\Flysystem\CalculateChecksumFromStream;
use League\Flysystem\ChecksumProvider;
use League\Flysystem\Config;
Expand Down Expand Up @@ -35,27 +37,8 @@ class BunnyCDNAdapter implements FilesystemAdapter, PublicUrlGenerator, Checksum
{
use CalculateChecksumFromStream;

/**
* Pull Zone URL
*
* @var string
*/
private string $pullzone_url;

/**
* @var BunnyCDNClient
*/
private BunnyCDNClient $client;

/**
* @param BunnyCDNClient $client
* @param string $pullzone_url
*/
public function __construct(BunnyCDNClient $client, string $pullzone_url = '')
public function __construct(private BunnyCDNClient $client, private string $pullzone_url = '')
{
$this->client = $client;
$this->pullzone_url = $pullzone_url;

if (\func_num_args() > 2 && (string) \func_get_arg(2) !== '') {
throw new \RuntimeException('PrefixPath is no longer supported directly. Use PathPrefixedAdapter instead: https://flysystem.thephpleague.com/docs/adapter/path-prefixing/');
}
Expand All @@ -70,12 +53,9 @@ public function __construct(BunnyCDNClient $client, string $pullzone_url = '')
public function copy($source, $destination, Config $config): void
{
try {
/** @var array<string> $files */
$files = iterator_to_array($this->getFiles($source));

$sourceLength = \strlen($source);

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

/**
* @param WriteBatchFile[] $writeBatches
* @param Config $config
* @return void
*/
public function writeBatch(array $writeBatches, Config $config): void
{
$concurrency = (int) $config->get('concurrency', 50);

foreach (\array_chunk($writeBatches, $concurrency) as $batch) {
$requests = function () use ($batch) {
/** @var WriteBatchFile $file */
foreach ($batch as $file) {
yield $this->client->getUploadRequest($file->targetPath, \file_get_contents($file->localPath));
}
};

$pool = new Pool($this->client->client, $requests(), [
'concurrency' => $concurrency,
'rejected' => function (RequestException $reason, int $index) {
throw UnableToWriteFile::atLocation($index, $reason->getMessage());
},
]);

$pool->promise()->wait();
}
}

/**
* @param $path
* @return resource
Expand Down
74 changes: 35 additions & 39 deletions src/BunnyCDNClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,13 @@

class BunnyCDNClient
{
public string $storage_zone_name;

private string $api_key;

private string $region;

public Guzzle $client;

public function __construct(string $storage_zone_name, string $api_key, string $region = BunnyCDNRegion::FALKENSTEIN)
{
$this->storage_zone_name = $storage_zone_name;
$this->api_key = $api_key;
$this->region = $region;

public function __construct(
public string $storage_zone_name,
private string $api_key,
private string $region = BunnyCDNRegion::FALKENSTEIN
) {
$this->client = new Guzzle();
}

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

public function createRequest(string $path, string $method = 'GET', array $options = []): Request
public function createRequest(string $path, string $method = 'GET', array $headers = [], $body = null): Request
{
return new Request($method,
return new Request(
$method,
self::get_base_url($this->region).Util::normalizePath('/'.$this->storage_zone_name.'/').$path,
array_merge_recursive([
'headers' => [
'Accept' => '*/*',
'AccessKey' => $this->api_key, // Honestly... Why do I have to specify this twice... @BunnyCDN
],
], $options)
array_merge([
'Accept' => '*/*',
'AccessKey' => $this->api_key,
], $headers),
$body
);
}

/**
* @throws ClientExceptionInterface
*/
private function request(string $path, string $method = 'GET', array $options = []): mixed
private function request(Request $request, array $options = []): mixed
{
$request = $this->createRequest($path, $method, $options);

$contents = $this->client->sendRequest($request)->getBody()->getContents();
$contents = $this->client->send($request, $options)->getBody()->getContents();

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

// Throw an exception if we don't get back an array
if (! is_array($listing)) {
Expand Down Expand Up @@ -107,7 +98,7 @@ public function list(string $path): array
public function download(string $path): string
{
try {
$content = $this->request($path.'?download');
$content = $this->request($this->createRequest($path.'?download'));

if (\is_array($content)) {
return \json_encode($content);
Expand All @@ -134,7 +125,7 @@ public function download(string $path): string
public function stream(string $path)
{
try {
return $this->createRequest($path, 'GET', ['stream' => true])->getBody()->detach();
return $this->request($this->createRequest($path), ['stream' => true])->getBody()->detach();
// @codeCoverageIgnoreStart
} catch (GuzzleException $e) {
throw match ($e->getCode()) {
Expand All @@ -145,6 +136,18 @@ public function stream(string $path)
// @codeCoverageIgnoreEnd
}

public function getUploadRequest(string $path, $contents): Request
{
return $this->createRequest(
$path,
'PUT',
[
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
],
$contents
);
}

/**
* @param string $path
* @param $contents
Expand All @@ -155,12 +158,7 @@ public function stream(string $path)
public function upload(string $path, $contents): mixed
{
try {
return $this->request($path, 'PUT', [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
],
'body' => $contents,
]);
return $this->request($this->getUploadRequest($path, $contents));
// @codeCoverageIgnoreStart
} catch (GuzzleException $e) {
throw new BunnyCDNException($e->getMessage());
Expand All @@ -177,11 +175,9 @@ public function upload(string $path, $contents): mixed
public function make_directory(string $path): mixed
{
try {
return $this->request(Util::normalizePath($path).'/', 'PUT', [
'headers' => [
'Content-Length' => 0,
],
]);
return $this->request($this->createRequest(Util::normalizePath($path).'/', 'PUT', [
'Content-Length' => 0,
]));
// @codeCoverageIgnoreStart
} catch (GuzzleException $e) {
throw match ($e->getCode()) {
Expand All @@ -202,7 +198,7 @@ public function make_directory(string $path): mixed
public function delete(string $path): mixed
{
try {
return $this->request($path, 'DELETE');
return $this->request($this->createRequest($path, 'DELETE'));
// @codeCoverageIgnoreStart
} catch (GuzzleException $e) {
throw match ($e->getCode()) {
Expand Down
12 changes: 12 additions & 0 deletions src/WriteBatchFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace PlatformCommunity\Flysystem\BunnyCDN;

class WriteBatchFile
{
public function __construct(
public string $localPath,
public string $targetPath,
) {
}
}

0 comments on commit 3a6e1ea

Please sign in to comment.