-
Notifications
You must be signed in to change notification settings - Fork 58
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
Better S3 client creation #22
Conversation
This is awesome man! I used your idea to adapt S3File to my needs and it works like a charm! An idea that I've implemented is to add a Here's my custom S3File without your PR, just pass an instance of this class to the <?php
namespace App\Services;
use Aws\S3\S3Client;
use Illuminate\Config\Repository;
use Psr\Http\Message\StreamInterface;
use STS\ZipStream\Models\File;
use function GuzzleHttp\Psr7\stream_for;
class StreamS3File extends File
{
protected ?string $region = null;
protected ?S3Client $client = null;
protected int $size = 0;
public function calculateFilesize(): int
{
if ($this->size) {
return $this->size;
}
$this->size = (int)$this->getS3Client()->headObject([
'Bucket' => $this->getBucket(),
'Key' => $this->getKey()
])->get('ContentLength');
return $this->size;
}
public function setSize(int $size): self
{
$this->size = $size;
return $this;
}
public function setS3Client(S3Client $client)
{
$this->client = $client;
return $this;
}
public function getS3Client(): S3Client
{
if (!$this->client) {
/** @var Repository $config */
$config = app()->make('config');
$this->client = new S3Client([
'credentials' => [
'key' => $config->get('filesystems.disks.s3.key'),
'secret' => $config->get('filesystems.disks.s3.secret')
],
'version' => 'latest',
'endpoint' => $config->get('filesystems.disks.s3.endpoint'),
'use_path_style_endpoint' => false,
'region' => $config->get('filesystems.disks.s3.region')
]);
}
return $this->client;
}
public function getBucket(): string
{
return parse_url($this->getSource(), PHP_URL_HOST);
}
public function getKey(): string
{
return ltrim(parse_url($this->getSource(), PHP_URL_PATH), "/");
}
protected function buildReadableStream(): StreamInterface
{
return $this->getS3Client()->getObject([
'Bucket' => $this->getBucket(),
'Key' => $this->getKey()
])->get('Body');
}
protected function buildWritableStream(): StreamInterface
{
$this->getS3Client()->registerStreamWrapper();
return stream_for(fopen($this->getSource(), 'w'));
}
} |
Good call. I just added a The following should work:
|
Instead of creating the S3 client directly in the S3File class, we'll now wire it up in the service provider. This way consumers can re-wire it up if they need to.
Additionally, this alters the config file structure just a bit, with the
aws
section matching the array structure passed to a new S3Client instance. This way consumers can publish the config file and directly control how the S3 client is created.