Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add writeBatch #81

Merged
merged 4 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "3.x-dev"
}
}
}
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->guzzleClient, $requests(), [
'concurrency' => $concurrency,
'rejected' => function (RequestException|RuntimeException $reason, int $index) {
throw UnableToWriteFile::atLocation($index, $reason->getMessage());
},
]);

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

/**
* @param $path
* @return resource
Expand Down
100 changes: 45 additions & 55 deletions src/BunnyCDNClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,21 @@

use GuzzleHttp\Client as Guzzle;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;
use PlatformCommunity\Flysystem\BunnyCDN\Exceptions\BunnyCDNException;
use PlatformCommunity\Flysystem\BunnyCDN\Exceptions\NotFoundException;
use Psr\Http\Client\ClientExceptionInterface;

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;

$this->client = new Guzzle();
public Guzzle $guzzleClient;

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

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

/**
* @throws GuzzleException
*/
private function request(string $path, string $method = 'GET', array $options = []): mixed
public function createRequest(string $path, string $method = 'GET', array $headers = [], $body = null): Request
{
$response = $this->client->request(
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
);
}

$contents = $response->getBody()->getContents();
/**
* @throws ClientExceptionInterface
*/
private function request(Request $request, array $options = []): mixed
{
$contents = $this->guzzleClient->send($request, $options)->getBody()->getContents();

return json_decode($contents, true) ?? $contents;
}
Expand All @@ -71,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 @@ -101,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 @@ -128,17 +125,7 @@ public function download(string $path): string
public function stream(string $path)
{
try {
return $this->client->request(
'GET',
self::get_base_url($this->region).Util::normalizePath('/'.$this->storage_zone_name.'/').$path,
array_merge_recursive([
'stream' => true,
'headers' => [
'Accept' => '*/*',
'AccessKey' => $this->api_key, // Honestly... Why do I have to specify this twice... @BunnyCDN
],
])
)->getBody()->detach();
return $this->guzzleClient->send($this->createRequest($path), ['stream' => true])->getBody()->detach();
// @codeCoverageIgnoreStart
} catch (GuzzleException $e) {
throw match ($e->getCode()) {
Expand All @@ -149,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 @@ -159,17 +158,10 @@ 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 match ($e->getCode()) {
default => new BunnyCDNException($e->getMessage())
};
throw new BunnyCDNException($e->getMessage());
}
// @codeCoverageIgnoreEnd
}
Expand All @@ -183,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 @@ -208,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,
) {
}
}
Loading
Loading