diff --git a/src/AsyncAwsS3/AsyncAwsS3Adapter.php b/src/AsyncAwsS3/AsyncAwsS3Adapter.php index c9a293b92..4763837f2 100644 --- a/src/AsyncAwsS3/AsyncAwsS3Adapter.php +++ b/src/AsyncAwsS3/AsyncAwsS3Adapter.php @@ -254,6 +254,17 @@ public function fileSize(string $path): FileAttributes return $attributes; } + public function extraMetadata(string $path): FileAttributes + { + $attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_EXTRA_METADATA); + + if (null === $attributes->extraMetadata()) { + throw UnableToRetrieveMetadata::extraMetadata($path); + } + + return $attributes; + } + public function listContents(string $path, bool $deep): iterable { $prefix = trim($this->prefixer->prefixPath($path), '/'); diff --git a/src/AwsS3V3/AwsS3V3Adapter.php b/src/AwsS3V3/AwsS3V3Adapter.php index 15b7eb26d..f336b4a2f 100644 --- a/src/AwsS3V3/AwsS3V3Adapter.php +++ b/src/AwsS3V3/AwsS3V3Adapter.php @@ -349,6 +349,17 @@ public function fileSize(string $path): FileAttributes return $attributes; } + public function extraMetadata(string $path): FileAttributes + { + $attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_EXTRA_METADATA); + + if ($attributes->extraMetadata() === null) { + throw UnableToRetrieveMetadata::extraMetadata($path); + } + + return $attributes; + } + public function listContents(string $path, bool $deep): iterable { $prefix = trim($this->prefixer->prefixPath($path), '/'); diff --git a/src/Filesystem.php b/src/Filesystem.php index f66574d68..bfe82128d 100644 --- a/src/Filesystem.php +++ b/src/Filesystem.php @@ -125,6 +125,11 @@ public function mimeType(string $path): string return $this->adapter->mimeType($this->pathNormalizer->normalizePath($path))->mimeType(); } + public function extraMetadata(string $path): array + { + return $this->adapter->extraMetadata($this->pathNormalizer->normalizePath($path))->extraMetadata(); + } + public function setVisibility(string $path, string $visibility): void { $this->adapter->setVisibility($this->pathNormalizer->normalizePath($path), $visibility); diff --git a/src/FilesystemAdapter.php b/src/FilesystemAdapter.php index 6dcb51e40..21bee4918 100644 --- a/src/FilesystemAdapter.php +++ b/src/FilesystemAdapter.php @@ -87,6 +87,12 @@ public function lastModified(string $path): FileAttributes; */ public function fileSize(string $path): FileAttributes; + /** + * @throws UnableToRetrieveMetadata + * @throws FilesystemException + */ + public function extraMetadata(string $path): FileAttributes; + /** * @return iterable * diff --git a/src/FilesystemReader.php b/src/FilesystemReader.php index 63145d091..80d238006 100644 --- a/src/FilesystemReader.php +++ b/src/FilesystemReader.php @@ -63,4 +63,10 @@ public function mimeType(string $path): string; * @throws FilesystemException */ public function visibility(string $path): string; + + /** + * @throws UnableToRetrieveMetadata + * @throws FilesystemException + */ + public function extraMetadata(string $path): array; } diff --git a/src/Ftp/FtpAdapter.php b/src/Ftp/FtpAdapter.php index 9afd94462..621a8ca58 100644 --- a/src/Ftp/FtpAdapter.php +++ b/src/Ftp/FtpAdapter.php @@ -332,6 +332,11 @@ public function visibility(string $path): FileAttributes return $this->fetchMetadata($path, FileAttributes::ATTRIBUTE_VISIBILITY); } + public function extraMetadata(string $path): FileAttributes + { + return $this->fetchMetadata($path, FileAttributes::ATTRIBUTE_EXTRA_METADATA); + } + public function fileSize(string $path): FileAttributes { $location = $this->prefixer->prefixPath($path); diff --git a/src/GoogleCloudStorage/GoogleCloudStorageAdapter.php b/src/GoogleCloudStorage/GoogleCloudStorageAdapter.php index c5be20241..321c55b67 100644 --- a/src/GoogleCloudStorage/GoogleCloudStorageAdapter.php +++ b/src/GoogleCloudStorage/GoogleCloudStorageAdapter.php @@ -195,6 +195,11 @@ public function fileSize(string $path): FileAttributes return $this->fileAttributes($path, 'fileSize'); } + public function extraMetadata(string $path): FileAttributes + { + return $this->fileAttributes($path, 'extraMetadata'); + } + private function fileAttributes(string $path, string $type): FileAttributes { $exception = null; diff --git a/src/InMemory/InMemoryFile.php b/src/InMemory/InMemoryFile.php index 871b67060..47c28a1a2 100644 --- a/src/InMemory/InMemoryFile.php +++ b/src/InMemory/InMemoryFile.php @@ -27,6 +27,11 @@ class InMemoryFile */ private $visibility; + /** + * @var array[] + */ + private $extraMetadata; + public function updateContents(string $contents): void { $this->contents = $contents; @@ -75,4 +80,14 @@ public function visibility(): ?string { return $this->visibility; } + + public function extraMetadata(): array + { + return $this->extraMetadata; + } + + public function setExtraMetadata(array $extraMetadata): void + { + $this->extraMetadata = $extraMetadata; + } } diff --git a/src/InMemory/InMemoryFilesystemAdapter.php b/src/InMemory/InMemoryFilesystemAdapter.php index 4c32bf167..8a6d3b0b5 100644 --- a/src/InMemory/InMemoryFilesystemAdapter.php +++ b/src/InMemory/InMemoryFilesystemAdapter.php @@ -168,6 +168,17 @@ public function fileSize(string $path): FileAttributes return new FileAttributes($path, $this->files[$path]->fileSize()); } + public function extraMetadata(string $path): FileAttributes + { + $path = $this->preparePath($path); + + if (array_key_exists($path, $this->files) === false) { + throw UnableToRetrieveMetadata::extraMetadata($path, 'file does not exist'); + } + + return new FileAttributes($path, null, null, null, null, $this->files[$path]->extraMetadata()); + } + public function listContents(string $path, bool $deep): iterable { $prefix = rtrim($this->preparePath($path), '/') . '/'; diff --git a/src/Local/LocalFilesystemAdapter.php b/src/Local/LocalFilesystemAdapter.php index 0e635cbb0..55e549110 100644 --- a/src/Local/LocalFilesystemAdapter.php +++ b/src/Local/LocalFilesystemAdapter.php @@ -377,6 +377,11 @@ public function mimeType(string $path): FileAttributes return new FileAttributes($path, null, null, null, $mimeType); } + public function extraMetadata(string $path): FileAttributes + { + throw UnableToRetrieveMetadata::extraMetadata($path, 'No extra metadata available for local files'); + } + public function lastModified(string $path): FileAttributes { $location = $this->prefixer->prefixPath($path); diff --git a/src/PhpseclibV2/SftpAdapter.php b/src/PhpseclibV2/SftpAdapter.php index ef37fcbc9..05abb858e 100644 --- a/src/PhpseclibV2/SftpAdapter.php +++ b/src/PhpseclibV2/SftpAdapter.php @@ -251,6 +251,11 @@ public function visibility(string $path): FileAttributes return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_VISIBILITY); } + public function extraMetadata(string $path): FileAttributes + { + return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_EXTRA_METADATA); + } + public function listContents(string $path, bool $deep): iterable { $connection = $this->connectionProvider->provideConnection(); diff --git a/src/PhpseclibV3/SftpAdapter.php b/src/PhpseclibV3/SftpAdapter.php index 63d061e15..de6e12220 100644 --- a/src/PhpseclibV3/SftpAdapter.php +++ b/src/PhpseclibV3/SftpAdapter.php @@ -251,6 +251,11 @@ public function visibility(string $path): FileAttributes return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_VISIBILITY); } + public function extraMetadata(string $path): FileAttributes + { + return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_EXTRA_METADATA); + } + public function listContents(string $path, bool $deep): iterable { $connection = $this->connectionProvider->provideConnection(); diff --git a/src/UnableToRetrieveMetadata.php b/src/UnableToRetrieveMetadata.php index 11cec7f99..84f7de8ca 100644 --- a/src/UnableToRetrieveMetadata.php +++ b/src/UnableToRetrieveMetadata.php @@ -44,6 +44,11 @@ public static function mimeType(string $location, string $reason = '', Throwable return static::create($location, FileAttributes::ATTRIBUTE_MIME_TYPE, $reason, $previous); } + public static function extraMetadata(string $location, string $reason = '', Throwable $previous = null): self + { + return static::create($location, FileAttributes::ATTRIBUTE_EXTRA_METADATA, $reason, $previous); + } + public static function create(string $location, string $type, string $reason = '', Throwable $previous = null): self { $e = new static("Unable to retrieve the $type for file at location: $location. {$reason}", 0, $previous);