Skip to content

Commit

Permalink
Add initial metadata implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
frankdejonge committed Sep 25, 2024
1 parent 8f4d6e5 commit 7da6af4
Show file tree
Hide file tree
Showing 65 changed files with 331 additions and 1,606 deletions.
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
}
},
"require": {
"php": "^8.0.2",
"league/flysystem-local": "^3.0.0",
"php": "^8.1",
"league/flysystem-local": "^4.0.0",
"league/mime-type-detection": "^1.0.0"
},
"require-dev": {
Expand Down Expand Up @@ -61,7 +61,7 @@
"type": "package",
"package": {
"name": "league/flysystem-local",
"version": "3.0.0",
"version": "4.0.0",
"dist": {
"type": "path",
"url": "src/Local"
Expand Down
32 changes: 31 additions & 1 deletion src/AdapterTestUtilities/FilesystemAdapterTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace League\Flysystem\AdapterTestUtilities;

use function json_encode;
use const PHP_EOL;
use DateInterval;
use DateTimeImmutable;
Expand Down Expand Up @@ -225,6 +226,35 @@ public function writing_a_file_with_an_empty_stream(): void
});
}

/**
* @test
*/
public function listing_metadata_for_a_file(): void
{
$this->givenWeHaveAnExistingFile('something.csv', '');

$metadata = $this->adapter()->metadata('something.csv', new Config);

$this->assertFalse($metadata->isDir());
$this->assertTrue($metadata->isFile());
}

/**
* @test
*/
public function retrieving_metadata_for_a_directory(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->createDirectory('somewhere/here/', new Config());

$metadata = $adapter->metadata('somewhere/here/', new Config());

$this->assertTrue($metadata->isDir());
$this->assertFalse($metadata->isFile());
});
}

/**
* @test
*/
Expand Down Expand Up @@ -539,7 +569,7 @@ public function listing_a_toplevel_directory(): void
$this->runScenario(function () {
$contents = iterator_to_array($this->adapter()->listContents('', true));

$this->assertCount(2, $contents);
$this->assertCount(2, $contents, json_encode($contents));
});
}

Expand Down
10 changes: 9 additions & 1 deletion src/AdapterTestUtilities/RetryOnTestException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace League\Flysystem\AdapterTestUtilities;

use function debug_backtrace;
use function fwrite;
use function get_class;
use const DEBUG_BACKTRACE_IGNORE_ARGS;
use const PHP_EOL;
use const STDOUT;
use League\Flysystem\FilesystemException;
Expand Down Expand Up @@ -68,6 +72,9 @@ protected function runScenario(callable $scenario): void
return;
}

$prevCaller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS|DEBUG_BACKTRACE_PROVIDE_OBJECT)[1];
$className = get_class($prevCaller['object']);
$caller = "$className::{$prevCaller['function']}";
$firstTryAt = \time();
$lastTryAt = $firstTryAt + 60;

Expand All @@ -80,7 +87,8 @@ protected function runScenario(callable $scenario): void
if ( ! $exception instanceof $this->exceptionTypeToRetryOn) {
throw $exception;
}
fwrite(STDOUT, 'Retrying ...' . PHP_EOL);
fwrite(STDOUT, $exception . PHP_EOL);
fwrite(STDOUT, "Retrying $caller..." . PHP_EOL);
sleep($this->timeoutForExceptionRetry);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/AdapterTestUtilities/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
]
},
"require": {
"php": "^8.0.2",
"php": "^8.1",
"league/flysystem": "^4.0.0"
},
"license": "MIT",
Expand Down
14 changes: 14 additions & 0 deletions src/AsyncAwsS3/AsyncAwsS3Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,20 @@ public function directoryExists(string $path): bool
}
}

public function metadata(string $path, Config $config): StorageAttributes
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];

try {
$result = $this->client->headObject($arguments);
$result->resolve();
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::create($path, StorageAttributes::ATTRIBUTE_METADATA, $exception->getMessage(), $exception);
}

return $this->mapS3ObjectMetadata($result, $path);
}

public function listContents(string $path, bool $deep): iterable
{
$path = trim($path, '/');
Expand Down
2 changes: 1 addition & 1 deletion src/AsyncAwsS3/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
},
"require": {
"php": "^8.0.2",
"php": "^8.1",
"league/flysystem": "^4.0.0",
"league/mime-type-detection": "^1.0.0",
"async-aws/s3": "^1.5 || ^2.0"
Expand Down
30 changes: 20 additions & 10 deletions src/AwsS3V3/AwsS3V3Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,7 @@ public function visibility(string $path): FileAttributes

private function fetchFileMetadata(string $path, string $type): FileAttributes
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
$command = $this->client->getCommand('HeadObject', $arguments);

try {
$result = $this->client->execute($command);
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::create($path, $type, '', $exception);
}

$attributes = $this->mapS3ObjectMetadata($result->toArray(), $path);
$attributes = $this->fetchMetadata($path, $type);

if ( ! $attributes instanceof FileAttributes) {
throw UnableToRetrieveMetadata::create($path, $type, '');
Expand Down Expand Up @@ -372,6 +363,25 @@ public function fileSize(string $path): FileAttributes
return $attributes;
}

public function metadata(string $path, Config $config): StorageAttributes
{
return $this->fetchMetadata($path, StorageAttributes::ATTRIBUTE_METADATA);
}

private function fetchMetadata(string $path, string $type): StorageAttributes
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
$command = $this->client->getCommand('HeadObject', $arguments);

try {
$result = $this->client->execute($command);
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::create($path, $type, '', $exception);
}

return $this->mapS3ObjectMetadata($result->toArray(), $path);
}

public function listContents(string $path, bool $deep): iterable
{
$prefix = trim($this->prefixer->prefixPath($path), '/');
Expand Down
2 changes: 1 addition & 1 deletion src/AwsS3V3/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
},
"require": {
"php": "^8.0.2",
"php": "^8.1",
"league/flysystem": "^4.0.0",
"league/mime-type-detection": "^1.0.0",
"aws/aws-sdk-php": "^3.295.10"
Expand Down
6 changes: 6 additions & 0 deletions src/AzureBlobStorage/AzureBlobStorageAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\PathPrefixer;
use League\Flysystem\StorageAttributes;
use League\Flysystem\UnableToCheckDirectoryExistence;
use League\Flysystem\UnableToCheckFileExistence;
use League\Flysystem\UnableToCopyFile;
Expand Down Expand Up @@ -347,6 +348,11 @@ public function publicUrl(string $path, Config $config): string
return $this->client->getBlobUrl($this->container, $location);
}

public function metadata(string $path, Config $config): StorageAttributes
{
return $this->fetchMetadata($this->prefixer->prefixPath($path));
}

public function checksum(string $path, Config $config): string
{
$algo = $config->get('checksum_algo', 'md5');
Expand Down
2 changes: 1 addition & 1 deletion src/AzureBlobStorage/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
},
"require": {
"php": "^8.0.2",
"php": "^8.1",
"league/flysystem": "^4.0.0",
"microsoft/azure-storage-blob": "^1.1"
},
Expand Down
5 changes: 5 additions & 0 deletions src/DecoratedAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public function directoryExists(string $path): bool
return $this->adapter->directoryExists($path);
}

public function metadata(string $path, Config $config): StorageAttributes
{
return $this->adapter->metadata($path, $config);
}

public function write(string $path, string $contents, Config $config): void
{
$this->adapter->write($path, $contents, $config);
Expand Down
7 changes: 5 additions & 2 deletions src/Filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,12 @@ public function visibility(string $path): string
return $this->adapter->visibility($this->pathNormalizer->normalizePath($path))->visibility();
}

public function metadata(string $path): StorageAttributes
public function metadata(string $path, array $config = []): StorageAttributes
{
return $this->adapter->metadata($this->pathNormalizer->normalizePath($path));
return $this->adapter->metadata(
$this->pathNormalizer->normalizePath($path),
$this->config->extend($config),
);
}

public function publicUrl(string $path, array $config = []): string
Expand Down
2 changes: 1 addition & 1 deletion src/FilesystemAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function fileSize(string $path): FileAttributes;
* @throws UnableToRetrieveMetadata
* @throws FilesystemException
*/
public function metadata(string $path): StorageAttributes;
public function metadata(string $path, Config $config): StorageAttributes;

/**
* @return iterable<StorageAttributes>
Expand Down
2 changes: 1 addition & 1 deletion src/FilesystemReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function visibility(string $path): string;
* @throws UnableToRetrieveMetadata
* @throws FilesystemException
*/
public function metadata(string $path): StorageAttributes;
public function metadata(string $path, array $config = []): StorageAttributes;

/**
* @throws UnableToGeneratePublicUrl
Expand Down
7 changes: 3 additions & 4 deletions src/Ftp/ConnectionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

namespace League\Flysystem\Ftp;

use FTP\Connection;

interface ConnectionProvider
{
/**
* @return resource
*/
public function createConnection(FtpConnectionOptions $options);
public function createConnection(FtpConnectionOptions $options): Connection;
}
7 changes: 3 additions & 4 deletions src/Ftp/ConnectivityChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

namespace League\Flysystem\Ftp;

use FTP\Connection;

interface ConnectivityChecker
{
/**
* @param resource $connection
*/
public function isConnected($connection): bool;
public function isConnected(Connection $connection): bool;
}
7 changes: 3 additions & 4 deletions src/Ftp/ConnectivityCheckerThatCanFail.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace League\Flysystem\Ftp;

use FTP\Connection;

class ConnectivityCheckerThatCanFail implements ConnectivityChecker
{
private bool $failNextCall = false;
Expand All @@ -17,10 +19,7 @@ public function failNextCall(): void
$this->failNextCall = true;
}

/**
* @inheritDoc
*/
public function isConnected($connection): bool
public function isConnected(Connection $connection): bool
{
if ($this->failNextCall) {
$this->failNextCall = false;
Expand Down
Loading

0 comments on commit 7da6af4

Please sign in to comment.