View source
<?php
namespace Drupal\flysystem_s3\Flysystem;
use Aws\Credentials\Credentials;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\flysystem\Plugin\FlysystemPluginInterface;
use Drupal\flysystem\Plugin\FlysystemUrlTrait;
use Drupal\flysystem\Plugin\ImageStyleGenerationTrait;
use Drupal\flysystem_s3\AwsCacheAdapter;
use Drupal\flysystem_s3\Flysystem\Adapter\S3Adapter;
use League\Flysystem\Config;
use Symfony\Component\DependencyInjection\ContainerInterface;
class S3 implements FlysystemPluginInterface, ContainerFactoryPluginInterface {
use ImageStyleGenerationTrait;
use FlysystemUrlTrait {
getExternalUrl as getDownloadlUrl;
}
protected $bucket;
protected $client;
protected $options;
protected $prefix;
protected $urlPrefix;
protected $isPublic;
public function __construct(S3Client $client, Config $config) {
$this->client = $client;
$this->bucket = $config
->get('bucket', '');
$this->prefix = $config
->get('prefix', '');
$this->isPublic = $config
->get('public', FALSE);
$this->options = $config
->get('options', []);
$this->urlPrefix = $this
->calculateUrlPrefix($config);
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$configuration = static::mergeConfiguration($container, $configuration);
$client_config = static::mergeClientConfiguration($container, $configuration);
$client = new S3Client($client_config);
unset($configuration['key'], $configuration['secret']);
return new static($client, new Config($configuration));
}
public static function mergeClientConfiguration(ContainerInterface $container, array $configuration) {
$client_config = [
'version' => 'latest',
'region' => $configuration['region'],
'endpoint' => $configuration['endpoint'],
];
if (isset($configuration['bucket_endpoint'])) {
$client_config['bucket_endpoint'] = $configuration['bucket_endpoint'];
}
if (isset($configuration['use_accelerate_endpoint'])) {
$client_config['use_accelerate_endpoint'] = $configuration['use_accelerate_endpoint'];
}
if (isset($configuration['use_dual_stack_endpoint'])) {
$client_config['use_dual_stack_endpoint'] = $configuration['use_dual_stack_endpoint'];
}
if (isset($configuration['use_path_style_endpoint'])) {
$client_config['use_path_style_endpoint'] = $configuration['use_path_style_endpoint'];
}
if (isset($configuration['key']) && isset($configuration['secret'])) {
$client_config['credentials'] = new Credentials($configuration['key'], $configuration['secret']);
return $client_config;
}
$client_config['credentials.cache'] = new AwsCacheAdapter($container
->get('cache.default'), 'flysystem_s3:');
return $client_config;
}
public static function mergeConfiguration(ContainerInterface $container, array $configuration) {
$protocol = $container
->get('request_stack')
->getCurrentRequest()
->getScheme();
return $configuration += [
'protocol' => $protocol,
'region' => 'us-east-1',
'endpoint' => NULL,
];
}
public function getAdapter() {
try {
$adapter = new S3Adapter($this->client, $this->bucket, $this->prefix, $this->options);
return $adapter;
} catch (S3Exception $e) {
$message = $e
->getMessage();
\Drupal::logger('flysystem_s3')
->error($message);
}
}
public function getExternalUrl($uri) {
if ($this->isPublic === FALSE) {
return $this
->getDownloadlUrl($uri);
}
$target = $this
->getTarget($uri);
if (strpos($target, 'styles/') === 0 && !file_exists($uri)) {
$this
->generateImageStyle($target);
}
return $this->urlPrefix . '/' . UrlHelper::encodePath($target);
}
public function ensure($force = FALSE) {
try {
$this
->getAdapter()
->listContents();
} catch (S3Exception $e) {
$message = $e
->getMessage();
\Drupal::logger('flysystem_s3')
->error($message);
}
if (!$this->client
->doesBucketExist($this->bucket)) {
return [
[
'severity' => RfcLogLevel::ERROR,
'message' => 'Bucket %bucket does not exist.',
'context' => [
'%bucket' => $this->bucket,
],
],
];
}
return [];
}
private function calculateUrlPrefix(Config $config) {
$protocol = $config
->get('protocol', 'http');
$cname = (string) $config
->get('cname');
$prefix = (string) $config
->get('prefix', '');
$prefix = $prefix === '' ? '' : '/' . UrlHelper::encodePath($prefix);
if ($cname !== '' && $config
->get('cname_is_bucket', TRUE)) {
return $protocol . '://' . $cname . $prefix;
}
$bucket = (string) $config
->get('bucket', '');
$bucket = $bucket === '' ? '' : '/' . UrlHelper::encodePath($bucket);
if ($cname === '') {
$cname = 's3-' . $config
->get('region', 'us-east-1') . '.amazonaws.com';
}
if ($cname === 's3-us-east-1.amazonaws.com') {
$cname = 's3.amazonaws.com';
}
return $protocol . '://' . $cname . $bucket . $prefix;
}
}