Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:
os: [ubuntu-latest]
include:
- laravel: 8.*
framework: ^8.24.0
framework: ^8.48.0
- laravel: 9.*
framework: ^9.0
- os: windows-latest
php: 8.0
laravel: 8.*
framework: ^8.24.0
framework: ^8.48.0
stability: prefer-stable
exclude:
- laravel: 9.*
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"facade/ignition-contracts": "^1.0",
"guzzlehttp/guzzle": "^6.3 || ^7.0",
"james-heinrich/getid3": "^1.9.21",
"laravel/framework": "^8.24.0 || ^9.0",
"laravel/framework": "^8.48.0 || ^9.0",
"laravel/helpers": "^1.1",
"league/commonmark": "^1.5 || ^2.2",
"league/csv": "^9.0",
Expand Down
254 changes: 45 additions & 209 deletions src/Imaging/GuzzleAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7\Uri;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\Util\MimeType;
use Psr\Http\Message\ResponseInterface;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\UnableToReadFile;

/**
* Uses Guzzle as a backend for HTTP URLs.
*/
class GuzzleAdapter implements AdapterInterface
class GuzzleAdapter implements FilesystemAdapter
{
/**
* Whether this endpoint supports head requests.
Expand All @@ -38,218 +34,112 @@ class GuzzleAdapter implements AdapterInterface
*/
protected $client;

/**
* The visibility of this adapter.
*
* @var string
*/
protected $visibility = AdapterInterface::VISIBILITY_PUBLIC;

/**
* Constructs a GuzzleAdapter object.
*
* @param string $base The base URL.
* @param \GuzzleHttp\ClientInterface $client An optional Guzzle client.
* @param bool $supportsHead Whether the client supports HEAD requests.
*/
public function __construct($base, ClientInterface $client = null, $supportsHead = true)
public function __construct($base, ClientInterface $client = null)
{
$this->base = rtrim($base, '/').'/';
$this->client = $client ?: new Client();
$this->supportsHead = $supportsHead;

if (isset(parse_url($base)['user'])) {
$this->visibility = AdapterInterface::VISIBILITY_PRIVATE;
}
}

/**
* Returns the base URL.
*
* @return string The base URL.
*/
public function getBaseUrl()
{
return $this->base;
}

/**
* {@inheritdoc}
*/
public function copy($path, $newpath)
public function fileExists(string $location): bool
{
return false;
return (bool) $this->head($location);
}

/**
* {@inheritdoc}
*/
public function createDir($path, Config $config)
public function directoryExists(string $location): bool
{
return false;
return $this->fileExists($location);
}

/**
* {@inheritdoc}
*/
public function delete($path)
public function read(string $path): string
{
return false;
}
if (! $response = $this->get($path)) {
throw UnableToReadFile::fromLocation($path);
}

/**
* {@inheritdoc}
*/
public function deleteDir($path)
{
return false;
return (string) $response->getBody();
}

/**
* {@inheritdoc}
*/
public function getMetadata($path)
public function readStream($path)
{
if (! $response = $this->head($path)) {
return false;
if (! $response = $this->get($path)) {
throw UnableToReadFile::fromLocation($path);
}

return [
'type' => 'file',
'path' => $path,
] + $this->getResponseMetadata($path, $response);
return $response->getBody()->detach();
}

/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
return $this->getMetadata($path);
}

/**
* {@inheritdoc}
*/
public function getSize($path)
public function setVisibility(string $path, string $visibility): void
{
return $this->getMetadata($path);
//
}

/**
* {@inheritdoc}
*/
public function getTimestamp($path)
public function write(string $path, string $contents, Config $config): void
{
return $this->getMetadata($path);
//
}

/**
* {@inheritdoc}
*/
public function getVisibility($path)
public function writeStream(string $path, $contents, Config $config): void
{
return [
'path' => $path,
'visibility' => $this->visibility,
];
//
}

/**
* {@inheritdoc}
*/
public function has($path)
public function mimeType(string $path): FileAttributes
{
return (bool) $this->head($path);
//
}

/**
* {@inheritdoc}
*/
public function listContents($directory = '', $recursive = false)
public function lastModified(string $path): FileAttributes
{
return [];
//
}

/**
* {@inheritdoc}
*/
public function read($path)
public function fileSize(string $path): FileAttributes
{
if (! $response = $this->get($path)) {
return false;
}

return [
'path' => $path,
'contents' => (string) $response->getBody(),
] + $this->getResponseMetadata($path, $response);
//
}

/**
* {@inheritdoc}
*/
public function readStream($path)
public function listContents(string $path, bool $deep): iterable
{
if (! $response = $this->get($path)) {
return false;
}

return [
'path' => $path,
'stream' => $response->getBody()->detach(),
] + $this->getResponseMetadata($path, $response);
//
}

/**
* {@inheritdoc}
*/
public function rename($path, $newpath)
public function move(string $source, string $destination, Config $config): void
{
return false;
//
}

/**
* {@inheritdoc}
*/
public function setVisibility($path, $visibility)
public function copy(string $source, string $destination, Config $config): void
{
throw new \LogicException('GuzzleAdapter does not support visibility. Path: '.$path.', visibility: '.$visibility);
//
}

/**
* {@inheritdoc}
*/
public function update($path, $contents, Config $conf)
public function createDirectory(string $path, Config $config): void
{
return false;
//
}

/**
* {@inheritdoc}
*/
public function updateStream($path, $resource, Config $config)
public function delete(string $path): void
{
return false;
//
}

/**
* {@inheritdoc}
*/
public function write($path, $contents, Config $config)
public function deleteDirectory(string $prefix): void
{
return false;
//
}

/**
* {@inheritdoc}
*/
public function writeStream($path, $resource, Config $config)
public function visibility(string $path): FileAttributes
{
return false;
//
}

/**
/*
* Performs a GET request.
*
* @param string $path The path to GET.
Expand All @@ -270,60 +160,6 @@ protected function get($path)
return $response;
}

/**
* Returns the mimetype of a response.
*
* @param string $path
* @param \Psr\Http\Message\ResponseInterface $response
* @return string
*/
protected function getMimetypeFromResponse($path, ResponseInterface $response)
{
if ($mimetype = $response->getHeader('Content-Type')) {
[$mimetype] = explode(';', reset($mimetype), 2);

return trim($mimetype);
}

// Try to guess from file extension.
$uri = new Uri($path);

return MimeType::detectByFilename($uri->getPath());
}

/**
* Returns the metadata array for a response.
*
* @param string $path
* @param \Psr\Http\Message\ResponseInterface $response
* @return array
*/
protected function getResponseMetadata($path, ResponseInterface $response)
{
$metadata = [
'visibility' => $this->visibility,
'mimetype' => $this->getMimetypeFromResponse($path, $response),
];

if ($last_modified = $response->getHeader('Last-Modified')) {
$last_modified = strtotime(reset($last_modified));

if ($last_modified !== false) {
$metadata['timestamp'] = $last_modified;
}
}

if ($length = $response->getHeader('Content-Length')) {
$length = reset($length);

if (is_numeric($length)) {
$metadata['size'] = (int) $length;
}
}

return $metadata;
}

/**
* Performs a HEAD request.
*
Expand Down
Loading