File manager - Edit - /home/autoph/public_html/projects/Rating-AutoHub/public/css/flysystem.tar
Back
readme.md 0000644 00000006416 15025032557 0006336 0 ustar 00 # League\Flysystem [](https://twitter.com/frankdejonge) [](https://github.com/thephpleague/flysystem) [](https://github.com/thephpleague/flysystem/releases) [](https://github.com/thephpleague/flysystem/blob/master/LICENSE) [](https://github.com/thephpleague/flysystem/actions?query=workflow%3A%22Quality+Assurance%22) [](https://packagist.org/packages/league/flysystem)  ## About Flysystem Flysystem is a file storage library for PHP. It provides one interface to interact with many types of filesystems. When you use Flysystem, you're not only protected from vendor lock-in, you'll also have a consistent experience for which ever storage is right for you. ## Getting Started * **[New in V3](https://flysystem.thephpleague.com/docs/what-is-new/)**: What is new in Flysystem V2/V3? * **[Architecture](https://flysystem.thephpleague.com/docs/architecture/)**: Flysystem's internal architecture * **[Flysystem API](https://flysystem.thephpleague.com/docs/usage/filesystem-api/)**: How to interact with your Flysystem instance * **[Upgrade from 1x](https://flysystem.thephpleague.com/docs/upgrade-from-1.x/)**: How to upgrade from 1.x/2.x ### Officially supported adapters * **[Local](https://flysystem.thephpleague.com/docs/adapter/local/)** * **[FTP](https://flysystem.thephpleague.com/docs/adapter/ftp/)** * **[SFTP](https://flysystem.thephpleague.com/docs/adapter/sftp-v3/)** * **[Memory](https://flysystem.thephpleague.com/docs/adapter/in-memory/)** * **[AWS S3](https://flysystem.thephpleague.com/docs/adapter/aws-s3-v3/)** * **[AsyncAws S3](https://flysystem.thephpleague.com/docs/adapter/async-aws-s3/)** * **[Google Cloud Storage](https://flysystem.thephpleague.com/docs/adapter/google-cloud-storage/)** * **[Azure Blob Storage](https://flysystem.thephpleague.com/docs/adapter/azure-blob-storage/)** * **[WebDAV](https://flysystem.thephpleague.com/docs/adapter/webdav/)** ### Third party Adapters * **[Gitlab](https://github.com/RoyVoetman/flysystem-gitlab-storage)** * **[Google Drive (using regular paths)](https://github.com/masbug/flysystem-google-drive-ext)** * **[bunny.net / BunnyCDN](https://github.com/PlatformCommunity/flysystem-bunnycdn/tree/v3)** * **[Sharepoint 365 / One Drive (Using MS Graph)](https://github.com/shitware-ltd/flysystem-msgraph)** * **[OneDrive](https://github.com/doerffler/flysystem-onedrive)** * **[Dropbox](https://github.com/spatie/flysystem-dropbox)** You can always [create an adapter](https://flysystem.thephpleague.com/v2/docs/advanced/creating-an-adapter/) yourself. ## Security If you discover any security related issues, please email info@frankdejonge.nl instead of using the issue tracker. ## Enjoy Oh, and if you've come down this far, you might as well follow me on [twitter](https://twitter.com/frankdejonge). docker-compose.yml 0000644 00000004174 15025032557 0010213 0 ustar 00 --- version: "3" services: sabredav: image: php:8.1-alpine3.15 restart: always volumes: - ./:/var/www/html/ ports: - "4040:4040" command: php -S 0.0.0.0:4040 /var/www/html/src/WebDAV/resources/server.php webdav: image: bytemark/webdav restart: always ports: - "4080:80" environment: AUTH_TYPE: Digest USERNAME: alice PASSWORD: secret1234 ANONYMOUS_METHODS: 'GET,OPTIONS' sftp: container_name: sftp restart: always image: atmoz/sftp volumes: - ./test_files/sftp/users.conf:/etc/sftp/users.conf - ./test_files/sftp/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key - ./test_files/sftp/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key - ./test_files/sftp/id_rsa.pub:/home/bar/.ssh/keys/id_rsa.pub ports: - "2222:22" sftp_eddsa_only: container_name: sftp_eddsa_only restart: always image: atmoz/sftp volumes: - ./test_files/sftp/users.conf:/etc/sftp/users.conf - ./test_files/sftp/sshd_custom_configs.sh:/etc/sftp.d/sshd_custom_configs.sh - ./test_files/sftp/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key ports: - "2223:22" ftp: container_name: ftp restart: always image: delfer/alpine-ftp-server environment: USERS: 'foo|pass|/home/foo/upload' ADDRESS: 'localhost' ports: - "2121:21" - "21000-21010:21000-21010" ftpd: container_name: ftpd restart: always environment: PUBLICHOST: localhost FTP_USER_NAME: foo FTP_USER_PASS: pass FTP_USER_HOME: /home/foo image: stilliard/pure-ftpd ports: - "2122:21" - "30000-30009:30000-30009" command: "/run.sh -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -P localhost" toxiproxy: container_name: toxiproxy restart: unless-stopped image: ghcr.io/shopify/toxiproxy command: "-host 0.0.0.0 -config /opt/toxiproxy/config.json" volumes: - ./test_files/toxiproxy/toxiproxy.json:/opt/toxiproxy/config.json:ro ports: - "8474:8474" # HTTP API - "8222:8222" # SFTP - "8121:8121" # FTP - "8122:8122" # FTPD composer.json 0000644 00000002734 15025032557 0007300 0 ustar 00 { "name": "league/flysystem", "description": "File storage abstraction for PHP", "keywords": [ "filesystem", "filesystems", "files", "storage", "aws", "s3", "ftp", "sftp", "webdav", "file", "cloud" ], "scripts": { "phpstan": "vendor/bin/phpstan analyse -l 6 src" }, "type": "library", "minimum-stability": "dev", "prefer-stable": true, "autoload": { "psr-4": { "League\\Flysystem\\": "src" } }, "require": { "php": "^8.0.2", "league/mime-type-detection": "^1.0.0" }, "require-dev": { "ext-zip": "*", "ext-fileinfo": "*", "ext-ftp": "*", "microsoft/azure-storage-blob": "^1.1", "phpunit/phpunit": "^9.5.11", "phpstan/phpstan": "^0.12.26", "phpseclib/phpseclib": "^3.0.14", "aws/aws-sdk-php": "^3.220.0", "composer/semver": "^3.0", "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", "async-aws/s3": "^1.5", "async-aws/simple-s3": "^1.1", "sabre/dav": "^4.3.1" }, "conflict": { "symfony/http-client": "<5.2", "guzzlehttp/ringphp": "<1.1.1", "guzzlehttp/guzzle": "<7.0", "aws/aws-sdk-php": "3.209.31 || 3.210.0", "phpseclib/phpseclib": "3.0.15" }, "license": "MIT", "authors": [ { "name": "Frank de Jonge", "email": "info@frankdejonge.nl" } ] } src/InvalidStreamProvided.php 0000644 00000000341 15025032557 0012305 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use InvalidArgumentException as BaseInvalidArgumentException; class InvalidStreamProvided extends BaseInvalidArgumentException implements FilesystemException { } src/ChecksumAlgoIsNotSupported.php 0000644 00000000251 15025032557 0013276 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use InvalidArgumentException; final class ChecksumAlgoIsNotSupported extends InvalidArgumentException { } src/UnixVisibility/VisibilityConverter.php 0000644 00000000621 15025032557 0015061 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\UnixVisibility; interface VisibilityConverter { public function forFile(string $visibility): int; public function forDirectory(string $visibility): int; public function inverseForFile(int $visibility): string; public function inverseForDirectory(int $visibility): string; public function defaultForDirectories(): int; } src/UnixVisibility/PortableVisibilityConverter.php 0000644 00000004521 15025032557 0016555 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\UnixVisibility; use League\Flysystem\PortableVisibilityGuard; use League\Flysystem\Visibility; class PortableVisibilityConverter implements VisibilityConverter { public function __construct( private int $filePublic = 0644, private int $filePrivate = 0600, private int $directoryPublic = 0755, private int $directoryPrivate = 0700, private string $defaultForDirectories = Visibility::PRIVATE ) { } public function forFile(string $visibility): int { PortableVisibilityGuard::guardAgainstInvalidInput($visibility); return $visibility === Visibility::PUBLIC ? $this->filePublic : $this->filePrivate; } public function forDirectory(string $visibility): int { PortableVisibilityGuard::guardAgainstInvalidInput($visibility); return $visibility === Visibility::PUBLIC ? $this->directoryPublic : $this->directoryPrivate; } public function inverseForFile(int $visibility): string { if ($visibility === $this->filePublic) { return Visibility::PUBLIC; } elseif ($visibility === $this->filePrivate) { return Visibility::PRIVATE; } return Visibility::PUBLIC; // default } public function inverseForDirectory(int $visibility): string { if ($visibility === $this->directoryPublic) { return Visibility::PUBLIC; } elseif ($visibility === $this->directoryPrivate) { return Visibility::PRIVATE; } return Visibility::PUBLIC; // default } public function defaultForDirectories(): int { return $this->defaultForDirectories === Visibility::PUBLIC ? $this->directoryPublic : $this->directoryPrivate; } /** * @param array<mixed> $permissionMap */ public static function fromArray(array $permissionMap, string $defaultForDirectories = Visibility::PRIVATE): PortableVisibilityConverter { return new PortableVisibilityConverter( $permissionMap['file']['public'] ?? 0644, $permissionMap['file']['private'] ?? 0600, $permissionMap['dir']['public'] ?? 0755, $permissionMap['dir']['private'] ?? 0700, $defaultForDirectories ); } } src/FilesystemWriter.php 0000644 00000002650 15025032557 0011374 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; interface FilesystemWriter { /** * @throws UnableToWriteFile * @throws FilesystemException */ public function write(string $location, string $contents, array $config = []): void; /** * @param mixed $contents * * @throws UnableToWriteFile * @throws FilesystemException */ public function writeStream(string $location, $contents, array $config = []): void; /** * @throws UnableToSetVisibility * @throws FilesystemException */ public function setVisibility(string $path, string $visibility): void; /** * @throws UnableToDeleteFile * @throws FilesystemException */ public function delete(string $location): void; /** * @throws UnableToDeleteDirectory * @throws FilesystemException */ public function deleteDirectory(string $location): void; /** * @throws UnableToCreateDirectory * @throws FilesystemException */ public function createDirectory(string $location, array $config = []): void; /** * @throws UnableToMoveFile * @throws FilesystemException */ public function move(string $source, string $destination, array $config = []): void; /** * @throws UnableToCopyFile * @throws FilesystemException */ public function copy(string $source, string $destination, array $config = []): void; } src/Filesystem.php 0000644 00000017070 15025032557 0010201 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use DateTimeInterface; use Generator; use League\Flysystem\UrlGeneration\ShardedPrefixPublicUrlGenerator; use League\Flysystem\UrlGeneration\PrefixPublicUrlGenerator; use League\Flysystem\UrlGeneration\PublicUrlGenerator; use League\Flysystem\UrlGeneration\TemporaryUrlGenerator; use Throwable; use function is_array; class Filesystem implements FilesystemOperator { use CalculateChecksumFromStream; private Config $config; private PathNormalizer $pathNormalizer; public function __construct( private FilesystemAdapter $adapter, array $config = [], PathNormalizer $pathNormalizer = null, private ?PublicUrlGenerator $publicUrlGenerator = null, private ?TemporaryUrlGenerator $temporaryUrlGenerator = null, ) { $this->config = new Config($config); $this->pathNormalizer = $pathNormalizer ?: new WhitespacePathNormalizer(); } public function fileExists(string $location): bool { return $this->adapter->fileExists($this->pathNormalizer->normalizePath($location)); } public function directoryExists(string $location): bool { return $this->adapter->directoryExists($this->pathNormalizer->normalizePath($location)); } public function has(string $location): bool { $path = $this->pathNormalizer->normalizePath($location); return $this->adapter->fileExists($path) || $this->adapter->directoryExists($path); } public function write(string $location, string $contents, array $config = []): void { $this->adapter->write( $this->pathNormalizer->normalizePath($location), $contents, $this->config->extend($config) ); } public function writeStream(string $location, $contents, array $config = []): void { /* @var resource $contents */ $this->assertIsResource($contents); $this->rewindStream($contents); $this->adapter->writeStream( $this->pathNormalizer->normalizePath($location), $contents, $this->config->extend($config) ); } public function read(string $location): string { return $this->adapter->read($this->pathNormalizer->normalizePath($location)); } public function readStream(string $location) { return $this->adapter->readStream($this->pathNormalizer->normalizePath($location)); } public function delete(string $location): void { $this->adapter->delete($this->pathNormalizer->normalizePath($location)); } public function deleteDirectory(string $location): void { $this->adapter->deleteDirectory($this->pathNormalizer->normalizePath($location)); } public function createDirectory(string $location, array $config = []): void { $this->adapter->createDirectory( $this->pathNormalizer->normalizePath($location), $this->config->extend($config) ); } public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing { $path = $this->pathNormalizer->normalizePath($location); $listing = $this->adapter->listContents($path, $deep); return new DirectoryListing($this->pipeListing($location, $deep, $listing)); } private function pipeListing(string $location, bool $deep, iterable $listing): Generator { try { foreach ($listing as $item) { yield $item; } } catch (Throwable $exception) { throw UnableToListContents::atLocation($location, $deep, $exception); } } public function move(string $source, string $destination, array $config = []): void { $this->adapter->move( $this->pathNormalizer->normalizePath($source), $this->pathNormalizer->normalizePath($destination), $this->config->extend($config) ); } public function copy(string $source, string $destination, array $config = []): void { $this->adapter->copy( $this->pathNormalizer->normalizePath($source), $this->pathNormalizer->normalizePath($destination), $this->config->extend($config) ); } public function lastModified(string $path): int { return $this->adapter->lastModified($this->pathNormalizer->normalizePath($path))->lastModified(); } public function fileSize(string $path): int { return $this->adapter->fileSize($this->pathNormalizer->normalizePath($path))->fileSize(); } public function mimeType(string $path): string { return $this->adapter->mimeType($this->pathNormalizer->normalizePath($path))->mimeType(); } public function setVisibility(string $path, string $visibility): void { $this->adapter->setVisibility($this->pathNormalizer->normalizePath($path), $visibility); } public function visibility(string $path): string { return $this->adapter->visibility($this->pathNormalizer->normalizePath($path))->visibility(); } public function publicUrl(string $path, array $config = []): string { $this->publicUrlGenerator ??= $this->resolvePublicUrlGenerator() ?: throw UnableToGeneratePublicUrl::noGeneratorConfigured($path); $config = $this->config->extend($config); return $this->publicUrlGenerator->publicUrl($path, $config); } public function temporaryUrl(string $path, DateTimeInterface $expiresAt, array $config = []): string { $generator = $this->temporaryUrlGenerator ?: $this->adapter; if ($generator instanceof TemporaryUrlGenerator) { return $generator->temporaryUrl($path, $expiresAt, $this->config->extend($config)); } throw UnableToGenerateTemporaryUrl::noGeneratorConfigured($path); } public function checksum(string $path, array $config = []): string { $config = $this->config->extend($config); if ( ! $this->adapter instanceof ChecksumProvider) { return $this->calculateChecksumFromStream($path, $config); } try { return $this->adapter->checksum($path, $config); } catch (ChecksumAlgoIsNotSupported) { return $this->calculateChecksumFromStream($path, $config); } } private function resolvePublicUrlGenerator(): ?PublicUrlGenerator { if ($publicUrl = $this->config->get('public_url')) { return match (true) { is_array($publicUrl) => new ShardedPrefixPublicUrlGenerator($publicUrl), default => new PrefixPublicUrlGenerator($publicUrl), }; } if ($this->adapter instanceof PublicUrlGenerator) { return $this->adapter; } return null; } /** * @param mixed $contents */ private function assertIsResource($contents): void { if (is_resource($contents) === false) { throw new InvalidStreamProvided( "Invalid stream provided, expected stream resource, received " . gettype($contents) ); } elseif ($type = get_resource_type($contents) !== 'stream') { throw new InvalidStreamProvided( "Invalid stream provided, expected stream resource, received resource of type " . $type ); } } /** * @param resource $resource */ private function rewindStream($resource): void { if (ftell($resource) !== 0 && stream_get_meta_data($resource)['seekable']) { rewind($resource); } } } src/UnableToMoveFile.php 0000644 00000001774 15025032557 0011221 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToMoveFile extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $source; /** * @var string */ private $destination; public function source(): string { return $this->source; } public function destination(): string { return $this->destination; } public static function fromLocationTo( string $sourcePath, string $destinationPath, Throwable $previous = null ): UnableToMoveFile { $message = $previous?->getMessage() ?? "Unable to move file from $sourcePath to $destinationPath"; $e = new static($message, 0, $previous); $e->source = $sourcePath; $e->destination = $destinationPath; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_MOVE; } } src/UnableToGenerateTemporaryUrl.php 0000644 00000001370 15025032557 0013623 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToGenerateTemporaryUrl extends RuntimeException implements FilesystemException { public function __construct(string $reason, string $path, ?Throwable $previous = null) { parent::__construct("Unable to generate temporary url for $path: $reason", 0, $previous); } public static function dueToError(string $path, Throwable $exception): static { return new static($exception->getMessage(), $path, $exception); } public static function noGeneratorConfigured(string $path, string $extraReason = ''): static { return new static('No generator was configured ' . $extraReason, $path); } } src/UnableToGeneratePublicUrl.php 0000644 00000001362 15025032557 0013060 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToGeneratePublicUrl extends RuntimeException implements FilesystemException { public function __construct(string $reason, string $path, ?Throwable $previous = null) { parent::__construct("Unable to generate public url for $path: $reason", 0, $previous); } public static function dueToError(string $path, Throwable $exception): static { return new static($exception->getMessage(), $path, $exception); } public static function noGeneratorConfigured(string $path, string $extraReason = ''): static { return new static('No generator was configured ' . $extraReason, $path); } } src/FilesystemReader.php 0000644 00000004171 15025032557 0011322 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use DateTimeInterface; /** * This interface contains everything to read from and inspect * a filesystem. All methods containing are non-destructive. * * @method string publicUrl(string $path, array $config = []) Will be added in 4.0 * @method string temporaryUrl(string $path, DateTimeInterface $expiresAt, array $config = []) Will be added in 4.0 * @method string checksum(string $path, array $config = []) Will be added in 4.0 */ interface FilesystemReader { public const LIST_SHALLOW = false; public const LIST_DEEP = true; /** * @throws FilesystemException * @throws UnableToCheckExistence */ public function fileExists(string $location): bool; /** * @throws FilesystemException * @throws UnableToCheckExistence */ public function directoryExists(string $location): bool; /** * @throws FilesystemException * @throws UnableToCheckExistence */ public function has(string $location): bool; /** * @throws UnableToReadFile * @throws FilesystemException */ public function read(string $location): string; /** * @return resource * * @throws UnableToReadFile * @throws FilesystemException */ public function readStream(string $location); /** * @return DirectoryListing<StorageAttributes> * * @throws FilesystemException * @throws UnableToListContents */ public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function lastModified(string $path): int; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function fileSize(string $path): int; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function mimeType(string $path): string; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function visibility(string $path): string; } src/Config.php 0000644 00000001365 15025032557 0007262 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use function array_merge; class Config { public const OPTION_VISIBILITY = 'visibility'; public const OPTION_DIRECTORY_VISIBILITY = 'directory_visibility'; public function __construct(private array $options = []) { } /** * @param mixed $default * * @return mixed */ public function get(string $property, $default = null) { return $this->options[$property] ?? $default; } public function extend(array $options): Config { return new Config(array_merge($this->options, $options)); } public function withDefaults(array $defaults): Config { return new Config($this->options + $defaults); } } src/UnableToListContents.php 0000644 00000001212 15025032557 0012127 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToListContents extends RuntimeException implements FilesystemOperationFailed { public static function atLocation(string $location, bool $deep, Throwable $previous): UnableToListContents { $message = "Unable to list contents for '$location', " . ($deep ? 'deep' : 'shallow') . " listing\n\n" . 'Reason: ' . $previous->getMessage(); return new UnableToListContents($message, 0, $previous); } public function operation(): string { return self::OPERATION_LIST_CONTENTS; } } src/StorageAttributes.php 0000644 00000002013 15025032557 0011517 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use ArrayAccess; use JsonSerializable; interface StorageAttributes extends JsonSerializable, ArrayAccess { public const ATTRIBUTE_PATH = 'path'; public const ATTRIBUTE_TYPE = 'type'; public const ATTRIBUTE_FILE_SIZE = 'file_size'; public const ATTRIBUTE_VISIBILITY = 'visibility'; public const ATTRIBUTE_LAST_MODIFIED = 'last_modified'; public const ATTRIBUTE_MIME_TYPE = 'mime_type'; public const ATTRIBUTE_EXTRA_METADATA = 'extra_metadata'; public const TYPE_FILE = 'file'; public const TYPE_DIRECTORY = 'dir'; public function path(): string; public function type(): string; public function visibility(): ?string; public function lastModified(): ?int; public static function fromArray(array $attributes): StorageAttributes; public function isFile(): bool; public function isDir(): bool; public function withPath(string $path): StorageAttributes; public function extraMetadata(): array; } src/UnableToResolveFilesystemMount.php 0000644 00000001323 15025032557 0014210 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; class UnableToResolveFilesystemMount extends RuntimeException implements FilesystemException { public static function becauseTheSeparatorIsMissing(string $path): UnableToResolveFilesystemMount { return new UnableToResolveFilesystemMount("Unable to resolve the filesystem mount because the path ($path) is missing a separator (://)."); } public static function becauseTheMountWasNotRegistered(string $mountIdentifier): UnableToResolveFilesystemMount { return new UnableToResolveFilesystemMount("Unable to resolve the filesystem mount because the mount ($mountIdentifier) was not registered."); } } src/DirectoryAttributes.php 0000644 00000004026 15025032557 0012065 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; class DirectoryAttributes implements StorageAttributes { use ProxyArrayAccessToProperties; private string $type = StorageAttributes::TYPE_DIRECTORY; public function __construct( private string $path, private ?string $visibility = null, private ?int $lastModified = null, private array $extraMetadata = []) { $this->path = trim($this->path, '/'); } public function path(): string { return $this->path; } public function type(): string { return $this->type; } public function visibility(): ?string { return $this->visibility; } public function lastModified(): ?int { return $this->lastModified; } public function extraMetadata(): array { return $this->extraMetadata; } public function isFile(): bool { return false; } public function isDir(): bool { return true; } public function withPath(string $path): self { $clone = clone $this; $clone->path = $path; return $clone; } public static function fromArray(array $attributes): self { return new DirectoryAttributes( $attributes[StorageAttributes::ATTRIBUTE_PATH], $attributes[StorageAttributes::ATTRIBUTE_VISIBILITY] ?? null, $attributes[StorageAttributes::ATTRIBUTE_LAST_MODIFIED] ?? null, $attributes[StorageAttributes::ATTRIBUTE_EXTRA_METADATA] ?? [] ); } /** * @inheritDoc */ public function jsonSerialize(): array { return [ StorageAttributes::ATTRIBUTE_TYPE => $this->type, StorageAttributes::ATTRIBUTE_PATH => $this->path, StorageAttributes::ATTRIBUTE_VISIBILITY => $this->visibility, StorageAttributes::ATTRIBUTE_LAST_MODIFIED => $this->lastModified, StorageAttributes::ATTRIBUTE_EXTRA_METADATA => $this->extraMetadata, ]; } } src/FilesystemAdapter.php 0000644 00000005340 15025032557 0011477 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; interface FilesystemAdapter { /** * @throws FilesystemException * @throws UnableToCheckExistence */ public function fileExists(string $path): bool; /** * @throws FilesystemException * @throws UnableToCheckExistence */ public function directoryExists(string $path): bool; /** * @throws UnableToWriteFile * @throws FilesystemException */ public function write(string $path, string $contents, Config $config): void; /** * @param resource $contents * * @throws UnableToWriteFile * @throws FilesystemException */ public function writeStream(string $path, $contents, Config $config): void; /** * @throws UnableToReadFile * @throws FilesystemException */ public function read(string $path): string; /** * @return resource * * @throws UnableToReadFile * @throws FilesystemException */ public function readStream(string $path); /** * @throws UnableToDeleteFile * @throws FilesystemException */ public function delete(string $path): void; /** * @throws UnableToDeleteDirectory * @throws FilesystemException */ public function deleteDirectory(string $path): void; /** * @throws UnableToCreateDirectory * @throws FilesystemException */ public function createDirectory(string $path, Config $config): void; /** * @throws InvalidVisibilityProvided * @throws FilesystemException */ public function setVisibility(string $path, string $visibility): void; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function visibility(string $path): FileAttributes; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function mimeType(string $path): FileAttributes; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function lastModified(string $path): FileAttributes; /** * @throws UnableToRetrieveMetadata * @throws FilesystemException */ public function fileSize(string $path): FileAttributes; /** * @return iterable<StorageAttributes> * * @throws FilesystemException */ public function listContents(string $path, bool $deep): iterable; /** * @throws UnableToMoveFile * @throws FilesystemException */ public function move(string $source, string $destination, Config $config): void; /** * @throws UnableToCopyFile * @throws FilesystemException */ public function copy(string $source, string $destination, Config $config): void; } src/UnableToWriteFile.php 0000644 00000001627 15025032557 0011402 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToWriteFile extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $location = ''; /** * @var string */ private $reason; public static function atLocation(string $location, string $reason = '', Throwable $previous = null): UnableToWriteFile { $e = new static(rtrim("Unable to write file at location: {$location}. {$reason}"), 0, $previous); $e->location = $location; $e->reason = $reason; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_WRITE; } public function reason(): string { return $this->reason; } public function location(): string { return $this->location; } } src/UnableToCheckExistence.php 0000644 00000001245 15025032557 0012371 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; class UnableToCheckExistence extends RuntimeException implements FilesystemOperationFailed { final public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) { parent::__construct($message, $code, $previous); } public static function forLocation(string $path, Throwable $exception = null): static { return new static("Unable to check existence for: {$path}", 0, $exception); } public function operation(): string { return FilesystemOperationFailed::OPERATION_EXISTENCE_CHECK; } } src/PathPrefixer.php 0000644 00000002206 15025032557 0010451 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use function rtrim; use function strlen; use function substr; final class PathPrefixer { private string $prefix = ''; public function __construct(string $prefix, private string $separator = '/') { $this->prefix = rtrim($prefix, '\\/'); if ($this->prefix !== '' || $prefix === $separator) { $this->prefix .= $separator; } } public function prefixPath(string $path): string { return $this->prefix . ltrim($path, '\\/'); } public function stripPrefix(string $path): string { /* @var string */ return substr($path, strlen($this->prefix)); } public function stripDirectoryPrefix(string $path): string { return rtrim($this->stripPrefix($path), '\\/'); } public function prefixDirectoryPath(string $path): string { $prefixedPath = $this->prefixPath(rtrim($path, '\\/')); if ($prefixedPath === '' || substr($prefixedPath, -1) === $this->separator) { return $prefixedPath; } return $prefixedPath . $this->separator; } } src/DirectoryListing.php 0000644 00000003420 15025032557 0011345 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use ArrayIterator; use Generator; use IteratorAggregate; use Traversable; /** * @template T */ class DirectoryListing implements IteratorAggregate { /** * @param iterable<T> $listing */ public function __construct(private iterable $listing) { } public function filter(callable $filter): DirectoryListing { $generator = (static function (iterable $listing) use ($filter): Generator { foreach ($listing as $item) { if ($filter($item)) { yield $item; } } })($this->listing); return new DirectoryListing($generator); } public function map(callable $mapper): DirectoryListing { $generator = (static function (iterable $listing) use ($mapper): Generator { foreach ($listing as $item) { yield $mapper($item); } })($this->listing); return new DirectoryListing($generator); } public function sortByPath(): DirectoryListing { $listing = $this->toArray(); usort($listing, function (StorageAttributes $a, StorageAttributes $b) { return $a->path() <=> $b->path(); }); return new DirectoryListing($listing); } /** * @return Traversable<T> */ public function getIterator(): Traversable { return $this->listing instanceof Traversable ? $this->listing : new ArrayIterator($this->listing); } /** * @return T[] */ public function toArray(): array { return $this->listing instanceof Traversable ? iterator_to_array($this->listing, false) : (array) $this->listing; } } src/UrlGeneration/TemporaryUrlGenerator.php 0000644 00000000571 15025032557 0015145 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\UrlGeneration; use DateTimeInterface; use League\Flysystem\Config; use League\Flysystem\UnableToGenerateTemporaryUrl; interface TemporaryUrlGenerator { /** * @throws UnableToGenerateTemporaryUrl */ public function temporaryUrl(string $path, DateTimeInterface $expiresAt, Config $config): string; } src/UrlGeneration/PrefixPublicUrlGenerator.php 0000644 00000000763 15025032557 0015562 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\UrlGeneration; use League\Flysystem\Config; use League\Flysystem\PathPrefixer; class PrefixPublicUrlGenerator implements PublicUrlGenerator { private PathPrefixer $prefixer; public function __construct(string $urlPrefix) { $this->prefixer = new PathPrefixer($urlPrefix, '/'); } public function publicUrl(string $path, Config $config): string { return $this->prefixer->prefixPath($path); } } src/UrlGeneration/ChainedPublicUrlGenerator.php 0000644 00000001353 15025032557 0015654 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\UrlGeneration; use League\Flysystem\Config; use League\Flysystem\UnableToGeneratePublicUrl; final class ChainedPublicUrlGenerator implements PublicUrlGenerator { /** * @param PublicUrlGenerator[] $generators */ public function __construct(private iterable $generators) { } public function publicUrl(string $path, Config $config): string { foreach ($this->generators as $generator) { try { return $generator->publicUrl($path, $config); } catch (UnableToGeneratePublicUrl) { } } throw new UnableToGeneratePublicUrl('No supported public url generator found.', $path); } } src/UrlGeneration/ShardedPrefixPublicUrlGenerator.php 0000644 00000001674 15025032557 0017057 0 ustar 00 <?php namespace League\Flysystem\UrlGeneration; use InvalidArgumentException; use League\Flysystem\Config; use League\Flysystem\PathPrefixer; use function array_map; use function count; use function crc32; final class ShardedPrefixPublicUrlGenerator implements PublicUrlGenerator { /** @var PathPrefixer[] */ private array $prefixes; private int $count; /** * @param string[] $prefixes */ public function __construct(array $prefixes) { $this->count = count($prefixes); if ($this->count === 0) { throw new InvalidArgumentException('At least one prefix is required.'); } $this->prefixes = array_map(static fn (string $prefix) => new PathPrefixer($prefix, '/'), $prefixes); } public function publicUrl(string $path, Config $config): string { $index = abs(crc32($path)) % $this->count; return $this->prefixes[$index]->prefixPath($path); } } src/UrlGeneration/PublicUrlGenerator.php 0000644 00000000471 15025032557 0014400 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\UrlGeneration; use League\Flysystem\Config; use League\Flysystem\UnableToGeneratePublicUrl; interface PublicUrlGenerator { /** * @throws UnableToGeneratePublicUrl */ public function publicUrl(string $path, Config $config): string; } src/CorruptedPathDetected.php 0000644 00000000474 15025032557 0012303 0 ustar 00 <?php namespace League\Flysystem; use RuntimeException; final class CorruptedPathDetected extends RuntimeException implements FilesystemException { public static function forPath(string $path): CorruptedPathDetected { return new CorruptedPathDetected("Corrupted path detected: " . $path); } } src/FilesystemOperationFailed.php 0000644 00000001672 15025032557 0013170 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; interface FilesystemOperationFailed extends FilesystemException { public const OPERATION_WRITE = 'WRITE'; public const OPERATION_UPDATE = 'UPDATE'; // not used public const OPERATION_EXISTENCE_CHECK = 'EXISTENCE_CHECK'; public const OPERATION_DIRECTORY_EXISTS = 'DIRECTORY_EXISTS'; public const OPERATION_FILE_EXISTS = 'FILE_EXISTS'; public const OPERATION_CREATE_DIRECTORY = 'CREATE_DIRECTORY'; public const OPERATION_DELETE = 'DELETE'; public const OPERATION_DELETE_DIRECTORY = 'DELETE_DIRECTORY'; public const OPERATION_MOVE = 'MOVE'; public const OPERATION_RETRIEVE_METADATA = 'RETRIEVE_METADATA'; public const OPERATION_COPY = 'COPY'; public const OPERATION_READ = 'READ'; public const OPERATION_SET_VISIBILITY = 'SET_VISIBILITY'; public const OPERATION_LIST_CONTENTS = 'LIST_CONTENTS'; public function operation(): string; } src/PortableVisibilityGuard.php 0000644 00000000777 15025032557 0012666 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; final class PortableVisibilityGuard { public static function guardAgainstInvalidInput(string $visibility): void { if ($visibility !== Visibility::PUBLIC && $visibility !== Visibility::PRIVATE) { $className = Visibility::class; throw InvalidVisibilityProvided::withVisibility( $visibility, "either {$className}::PUBLIC or {$className}::PRIVATE" ); } } } src/UnableToSetVisibility.php 0000644 00000001725 15025032557 0012312 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; use function rtrim; final class UnableToSetVisibility extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $location; /** * @var string */ private $reason; public function reason(): string { return $this->reason; } public static function atLocation(string $filename, string $extraMessage = '', Throwable $previous = null): self { $message = "Unable to set visibility for file {$filename}. $extraMessage"; $e = new static(rtrim($message), 0, $previous); $e->reason = $extraMessage; $e->location = $filename; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_SET_VISIBILITY; } public function location(): string { return $this->location; } } src/UnableToCheckFileExistence.php 0000644 00000000367 15025032557 0013175 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; class UnableToCheckFileExistence extends UnableToCheckExistence { public function operation(): string { return FilesystemOperationFailed::OPERATION_FILE_EXISTS; } } src/UnableToDeleteDirectory.php 0000644 00000001715 15025032557 0012575 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToDeleteDirectory extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $location = ''; /** * @var string */ private $reason; public static function atLocation( string $location, string $reason = '', Throwable $previous = null ): UnableToDeleteDirectory { $e = new static(rtrim("Unable to delete directory located at: {$location}. {$reason}"), 0, $previous); $e->location = $location; $e->reason = $reason; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_DELETE_DIRECTORY; } public function reason(): string { return $this->reason; } public function location(): string { return $this->location; } } src/UnableToReadFile.php 0000644 00000001634 15025032557 0011161 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToReadFile extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $location = ''; /** * @var string */ private $reason = ''; public static function fromLocation(string $location, string $reason = '', Throwable $previous = null): UnableToReadFile { $e = new static(rtrim("Unable to read file from location: {$location}. {$reason}"), 0, $previous); $e->location = $location; $e->reason = $reason; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_READ; } public function reason(): string { return $this->reason; } public function location(): string { return $this->location; } } src/Local/FallbackMimeTypeDetector.php 0000644 00000002475 15025032557 0013755 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\Local; use League\MimeTypeDetection\MimeTypeDetector; use function in_array; class FallbackMimeTypeDetector implements MimeTypeDetector { private const INCONCLUSIVE_MIME_TYPES = [ 'application/x-empty', 'text/plain', 'text/x-asm', 'application/octet-stream', 'inode/x-empty', ]; public function __construct( private MimeTypeDetector $detector, private array $inconclusiveMimetypes = self::INCONCLUSIVE_MIME_TYPES ) {} public function detectMimeType(string $path, $contents): ?string { return $this->detector->detectMimeType($path, $contents); } public function detectMimeTypeFromBuffer(string $contents): ?string { return $this->detector->detectMimeTypeFromBuffer($contents); } public function detectMimeTypeFromPath(string $path): ?string { return $this->detector->detectMimeTypeFromPath($path); } public function detectMimeTypeFromFile(string $path): ?string { $mimeType = $this->detector->detectMimeTypeFromFile($path); if ($mimeType !== null && ! in_array($mimeType, $this->inconclusiveMimetypes)) { return $mimeType; } return $this->detector->detectMimeTypeFromPath($path); } } src/Local/LocalFilesystemAdapter.php 0000644 00000034050 15025032557 0013504 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem\Local; use DirectoryIterator; use FilesystemIterator; use Generator; use League\Flysystem\ChecksumProvider; use League\Flysystem\Config; use League\Flysystem\DirectoryAttributes; use League\Flysystem\FileAttributes; use League\Flysystem\FilesystemAdapter; use League\Flysystem\PathPrefixer; use League\Flysystem\SymbolicLinkEncountered; use League\Flysystem\UnableToCopyFile; use League\Flysystem\UnableToCreateDirectory; use League\Flysystem\UnableToDeleteDirectory; use League\Flysystem\UnableToDeleteFile; use League\Flysystem\UnableToMoveFile; use League\Flysystem\UnableToProvideChecksum; use League\Flysystem\UnableToReadFile; use League\Flysystem\UnableToRetrieveMetadata; use League\Flysystem\UnableToSetVisibility; use League\Flysystem\UnableToWriteFile; use League\Flysystem\UnixVisibility\PortableVisibilityConverter; use League\Flysystem\UnixVisibility\VisibilityConverter; use League\MimeTypeDetection\FinfoMimeTypeDetector; use League\MimeTypeDetection\MimeTypeDetector; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use SplFileInfo; use function chmod; use function clearstatcache; use function dirname; use function error_clear_last; use function error_get_last; use function file_exists; use function file_put_contents; use function hash_file; use function is_dir; use function is_file; use function mkdir; use function rename; use const DIRECTORY_SEPARATOR; use const LOCK_EX; class LocalFilesystemAdapter implements FilesystemAdapter, ChecksumProvider { /** * @var int */ public const SKIP_LINKS = 0001; /** * @var int */ public const DISALLOW_LINKS = 0002; private PathPrefixer $prefixer; private VisibilityConverter $visibility; private MimeTypeDetector $mimeTypeDetector; private string $rootLocation; /** * @var bool */ private $rootLocationIsSetup = false; public function __construct( string $location, VisibilityConverter $visibility = null, private int $writeFlags = LOCK_EX, private int $linkHandling = self::DISALLOW_LINKS, MimeTypeDetector $mimeTypeDetector = null, bool $lazyRootCreation = false, ) { $this->prefixer = new PathPrefixer($location, DIRECTORY_SEPARATOR); $visibility ??= new PortableVisibilityConverter(); $this->visibility = $visibility; $this->rootLocation = $location; $this->mimeTypeDetector = $mimeTypeDetector ?: new FallbackMimeTypeDetector(new FinfoMimeTypeDetector()); if ( ! $lazyRootCreation) { $this->ensureRootDirectoryExists(); } } private function ensureRootDirectoryExists(): void { if ($this->rootLocationIsSetup) { return; } $this->ensureDirectoryExists($this->rootLocation, $this->visibility->defaultForDirectories()); } public function write(string $path, string $contents, Config $config): void { $this->writeToFile($path, $contents, $config); } public function writeStream(string $path, $contents, Config $config): void { $this->writeToFile($path, $contents, $config); } /** * @param resource|string $contents */ private function writeToFile(string $path, $contents, Config $config): void { $prefixedLocation = $this->prefixer->prefixPath($path); $this->ensureRootDirectoryExists(); $this->ensureDirectoryExists( dirname($prefixedLocation), $this->resolveDirectoryVisibility($config->get(Config::OPTION_DIRECTORY_VISIBILITY)) ); error_clear_last(); if (@file_put_contents($prefixedLocation, $contents, $this->writeFlags) === false) { throw UnableToWriteFile::atLocation($path, error_get_last()['message'] ?? ''); } if ($visibility = $config->get(Config::OPTION_VISIBILITY)) { $this->setVisibility($path, (string) $visibility); } } public function delete(string $path): void { $location = $this->prefixer->prefixPath($path); if ( ! file_exists($location)) { return; } error_clear_last(); if ( ! @unlink($location)) { throw UnableToDeleteFile::atLocation($location, error_get_last()['message'] ?? ''); } } public function deleteDirectory(string $prefix): void { $location = $this->prefixer->prefixPath($prefix); if ( ! is_dir($location)) { return; } $contents = $this->listDirectoryRecursively($location, RecursiveIteratorIterator::CHILD_FIRST); /** @var SplFileInfo $file */ foreach ($contents as $file) { if ( ! $this->deleteFileInfoObject($file)) { throw UnableToDeleteDirectory::atLocation($prefix, "Unable to delete file at " . $file->getPathname()); } } unset($contents); if ( ! @rmdir($location)) { throw UnableToDeleteDirectory::atLocation($prefix, error_get_last()['message'] ?? ''); } } private function listDirectoryRecursively( string $path, int $mode = RecursiveIteratorIterator::SELF_FIRST ): Generator { if ( ! is_dir($path)) { return; } yield from new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), $mode ); } protected function deleteFileInfoObject(SplFileInfo $file): bool { switch ($file->getType()) { case 'dir': return @rmdir((string) $file->getRealPath()); case 'link': return @unlink((string) $file->getPathname()); default: return @unlink((string) $file->getRealPath()); } } public function listContents(string $path, bool $deep): iterable { $location = $this->prefixer->prefixPath($path); if ( ! is_dir($location)) { return; } /** @var SplFileInfo[] $iterator */ $iterator = $deep ? $this->listDirectoryRecursively($location) : $this->listDirectory($location); foreach ($iterator as $fileInfo) { if ($fileInfo->isLink()) { if ($this->linkHandling & self::SKIP_LINKS) { continue; } throw SymbolicLinkEncountered::atLocation($fileInfo->getPathname()); } $path = $this->prefixer->stripPrefix($fileInfo->getPathname()); $lastModified = $fileInfo->getMTime(); $isDirectory = $fileInfo->isDir(); $permissions = octdec(substr(sprintf('%o', $fileInfo->getPerms()), -4)); $visibility = $isDirectory ? $this->visibility->inverseForDirectory($permissions) : $this->visibility->inverseForFile($permissions); yield $isDirectory ? new DirectoryAttributes(str_replace('\\', '/', $path), $visibility, $lastModified) : new FileAttributes( str_replace('\\', '/', $path), $fileInfo->getSize(), $visibility, $lastModified ); } } public function move(string $source, string $destination, Config $config): void { $sourcePath = $this->prefixer->prefixPath($source); $destinationPath = $this->prefixer->prefixPath($destination); $this->ensureRootDirectoryExists(); $this->ensureDirectoryExists( dirname($destinationPath), $this->resolveDirectoryVisibility($config->get(Config::OPTION_DIRECTORY_VISIBILITY)) ); if ( ! @rename($sourcePath, $destinationPath)) { throw UnableToMoveFile::fromLocationTo($sourcePath, $destinationPath); } } public function copy(string $source, string $destination, Config $config): void { $sourcePath = $this->prefixer->prefixPath($source); $destinationPath = $this->prefixer->prefixPath($destination); $this->ensureRootDirectoryExists(); $this->ensureDirectoryExists( dirname($destinationPath), $this->resolveDirectoryVisibility($config->get(Config::OPTION_DIRECTORY_VISIBILITY)) ); if ( ! @copy($sourcePath, $destinationPath)) { throw UnableToCopyFile::fromLocationTo($sourcePath, $destinationPath); } } public function read(string $path): string { $location = $this->prefixer->prefixPath($path); error_clear_last(); $contents = @file_get_contents($location); if ($contents === false) { throw UnableToReadFile::fromLocation($path, error_get_last()['message'] ?? ''); } return $contents; } public function readStream(string $path) { $location = $this->prefixer->prefixPath($path); error_clear_last(); $contents = @fopen($location, 'rb'); if ($contents === false) { throw UnableToReadFile::fromLocation($path, error_get_last()['message'] ?? ''); } return $contents; } protected function ensureDirectoryExists(string $dirname, int $visibility): void { if (is_dir($dirname)) { return; } error_clear_last(); if ( ! @mkdir($dirname, $visibility, true)) { $mkdirError = error_get_last(); } clearstatcache(true, $dirname); if ( ! is_dir($dirname)) { $errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : ''; throw UnableToCreateDirectory::atLocation($dirname, $errorMessage); } } public function fileExists(string $location): bool { $location = $this->prefixer->prefixPath($location); return is_file($location); } public function directoryExists(string $location): bool { $location = $this->prefixer->prefixPath($location); return is_dir($location); } public function createDirectory(string $path, Config $config): void { $this->ensureRootDirectoryExists(); $location = $this->prefixer->prefixPath($path); $visibility = $config->get(Config::OPTION_VISIBILITY, $config->get(Config::OPTION_DIRECTORY_VISIBILITY)); $permissions = $this->resolveDirectoryVisibility($visibility); if (is_dir($location)) { $this->setPermissions($location, $permissions); return; } error_clear_last(); if ( ! @mkdir($location, $permissions, true)) { throw UnableToCreateDirectory::atLocation($path, error_get_last()['message'] ?? ''); } } public function setVisibility(string $path, string $visibility): void { $path = $this->prefixer->prefixPath($path); $visibility = is_dir($path) ? $this->visibility->forDirectory($visibility) : $this->visibility->forFile( $visibility ); $this->setPermissions($path, $visibility); } public function visibility(string $path): FileAttributes { $location = $this->prefixer->prefixPath($path); clearstatcache(false, $location); error_clear_last(); $fileperms = @fileperms($location); if ($fileperms === false) { throw UnableToRetrieveMetadata::visibility($path, error_get_last()['message'] ?? ''); } $permissions = $fileperms & 0777; $visibility = $this->visibility->inverseForFile($permissions); return new FileAttributes($path, null, $visibility); } private function resolveDirectoryVisibility(?string $visibility): int { return $visibility === null ? $this->visibility->defaultForDirectories() : $this->visibility->forDirectory( $visibility ); } public function mimeType(string $path): FileAttributes { $location = $this->prefixer->prefixPath($path); error_clear_last(); if ( ! is_file($location)) { throw UnableToRetrieveMetadata::mimeType($location, 'No such file exists.'); } $mimeType = $this->mimeTypeDetector->detectMimeTypeFromFile($location); if ($mimeType === null) { throw UnableToRetrieveMetadata::mimeType($path, error_get_last()['message'] ?? ''); } return new FileAttributes($path, null, null, null, $mimeType); } public function lastModified(string $path): FileAttributes { $location = $this->prefixer->prefixPath($path); error_clear_last(); $lastModified = @filemtime($location); if ($lastModified === false) { throw UnableToRetrieveMetadata::lastModified($path, error_get_last()['message'] ?? ''); } return new FileAttributes($path, null, null, $lastModified); } public function fileSize(string $path): FileAttributes { $location = $this->prefixer->prefixPath($path); error_clear_last(); if (is_file($location) && ($fileSize = @filesize($location)) !== false) { return new FileAttributes($path, $fileSize); } throw UnableToRetrieveMetadata::fileSize($path, error_get_last()['message'] ?? ''); } public function checksum(string $path, Config $config): string { $algo = $config->get('checksum_algo', 'md5'); $location = $this->prefixer->prefixPath($path); error_clear_last(); $checksum = @hash_file($algo, $location); if ($checksum === false) { throw new UnableToProvideChecksum(error_get_last()['message'] ?? '', $path); } return $checksum; } private function listDirectory(string $location): Generator { $iterator = new DirectoryIterator($location); foreach ($iterator as $item) { if ($item->isDot()) { continue; } yield $item; } } private function setPermissions(string $location, int $visibility): void { error_clear_last(); if ( ! @chmod($location, $visibility)) { $extraMessage = error_get_last()['message'] ?? ''; throw UnableToSetVisibility::atLocation($this->prefixer->stripPrefix($location), $extraMessage); } } } src/UnableToMountFilesystem.php 0000644 00000001623 15025032557 0012653 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use LogicException; class UnableToMountFilesystem extends LogicException implements FilesystemException { /** * @param mixed $key */ public static function becauseTheKeyIsNotValid($key): UnableToMountFilesystem { return new UnableToMountFilesystem( 'Unable to mount filesystem, key was invalid. String expected, received: ' . gettype($key) ); } /** * @param mixed $filesystem */ public static function becauseTheFilesystemWasNotValid($filesystem): UnableToMountFilesystem { $received = is_object($filesystem) ? get_class($filesystem) : gettype($filesystem); return new UnableToMountFilesystem( 'Unable to mount filesystem, filesystem was invalid. Instance of ' . FilesystemOperator::class . ' expected, received: ' . $received ); } } src/CalculateChecksumFromStream.php 0000644 00000001431 15025032557 0013427 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use function hash_final; use function hash_init; use function hash_update_stream; trait CalculateChecksumFromStream { private function calculateChecksumFromStream(string $path, Config $config): string { try { $stream = $this->readStream($path); $algo = (string) $config->get('checksum_algo', 'md5'); $context = hash_init($algo); hash_update_stream($context, $stream); return hash_final($context); } catch (FilesystemException $exception) { throw new UnableToProvideChecksum($exception->getMessage(), $path, $exception); } } /** * @return resource */ abstract public function readStream(string $path); } src/UnreadableFileEncountered.php 0000644 00000001054 15025032557 0013106 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; final class UnreadableFileEncountered extends RuntimeException implements FilesystemException { /** * @var string */ private $location; public function location(): string { return $this->location; } public static function atLocation(string $location): UnreadableFileEncountered { $e = new static("Unreadable file encountered at location {$location}."); $e->location = $location; return $e; } } src/ChecksumProvider.php 0000644 00000000443 15025032557 0011326 0 ustar 00 <?php namespace League\Flysystem; interface ChecksumProvider { /** * @return string MD5 hash of the file contents * * @throws UnableToProvideChecksum * @throws ChecksumAlgoIsNotSupported */ public function checksum(string $path, Config $config): string; } src/SymbolicLinkEncountered.php 0000644 00000001023 15025032557 0012637 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; final class SymbolicLinkEncountered extends RuntimeException implements FilesystemException { private string $location; public function location(): string { return $this->location; } public static function atLocation(string $pathName): SymbolicLinkEncountered { $e = new static("Unsupported symbolic link encountered at location $pathName"); $e->location = $pathName; return $e; } } src/MountManager.php 0000644 00000033167 15025032557 0010457 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use DateTimeInterface; use Throwable; use function method_exists; use function sprintf; class MountManager implements FilesystemOperator { /** * @var array<string, FilesystemOperator> */ private $filesystems = []; /** * MountManager constructor. * * @param array<string,FilesystemOperator> $filesystems */ public function __construct(array $filesystems = []) { $this->mountFilesystems($filesystems); } public function fileExists(string $location): bool { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->fileExists($path); } catch (Throwable $exception) { throw UnableToCheckFileExistence::forLocation($location, $exception); } } public function has(string $location): bool { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->fileExists($path) || $filesystem->directoryExists($path); } catch (Throwable $exception) { throw UnableToCheckExistence::forLocation($location, $exception); } } public function directoryExists(string $location): bool { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->directoryExists($path); } catch (Throwable $exception) { throw UnableToCheckDirectoryExistence::forLocation($location, $exception); } } public function read(string $location): string { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->read($path); } catch (UnableToReadFile $exception) { throw UnableToReadFile::fromLocation($location, $exception->reason(), $exception); } } public function readStream(string $location) { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->readStream($path); } catch (UnableToReadFile $exception) { throw UnableToReadFile::fromLocation($location, $exception->reason(), $exception); } } public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing { /** @var FilesystemOperator $filesystem */ [$filesystem, $path, $mountIdentifier] = $this->determineFilesystemAndPath($location); return $filesystem ->listContents($path, $deep) ->map( function (StorageAttributes $attributes) use ($mountIdentifier) { return $attributes->withPath(sprintf('%s://%s', $mountIdentifier, $attributes->path())); } ); } public function lastModified(string $location): int { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->lastModified($path); } catch (UnableToRetrieveMetadata $exception) { throw UnableToRetrieveMetadata::lastModified($location, $exception->reason(), $exception); } } public function fileSize(string $location): int { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->fileSize($path); } catch (UnableToRetrieveMetadata $exception) { throw UnableToRetrieveMetadata::fileSize($location, $exception->reason(), $exception); } } public function mimeType(string $location): string { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->mimeType($path); } catch (UnableToRetrieveMetadata $exception) { throw UnableToRetrieveMetadata::mimeType($location, $exception->reason(), $exception); } } public function visibility(string $location): string { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { return $filesystem->visibility($path); } catch (UnableToRetrieveMetadata $exception) { throw UnableToRetrieveMetadata::visibility($location, $exception->reason(), $exception); } } public function write(string $location, string $contents, array $config = []): void { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { $filesystem->write($path, $contents, $config); } catch (UnableToWriteFile $exception) { throw UnableToWriteFile::atLocation($location, $exception->reason(), $exception); } } public function writeStream(string $location, $contents, array $config = []): void { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); $filesystem->writeStream($path, $contents, $config); } public function setVisibility(string $path, string $visibility): void { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($path); $filesystem->setVisibility($path, $visibility); } public function delete(string $location): void { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { $filesystem->delete($path); } catch (UnableToDeleteFile $exception) { throw UnableToDeleteFile::atLocation($location, $exception->reason(), $exception); } } public function deleteDirectory(string $location): void { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { $filesystem->deleteDirectory($path); } catch (UnableToDeleteDirectory $exception) { throw UnableToDeleteDirectory::atLocation($location, $exception->reason(), $exception); } } public function createDirectory(string $location, array $config = []): void { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($location); try { $filesystem->createDirectory($path, $config); } catch (UnableToCreateDirectory $exception) { throw UnableToCreateDirectory::dueToFailure($location, $exception); } } public function move(string $source, string $destination, array $config = []): void { /** @var FilesystemOperator $sourceFilesystem */ /* @var FilesystemOperator $destinationFilesystem */ [$sourceFilesystem, $sourcePath] = $this->determineFilesystemAndPath($source); [$destinationFilesystem, $destinationPath] = $this->determineFilesystemAndPath($destination); $sourceFilesystem === $destinationFilesystem ? $this->moveInTheSameFilesystem( $sourceFilesystem, $sourcePath, $destinationPath, $source, $destination ) : $this->moveAcrossFilesystems($source, $destination, $config); } public function copy(string $source, string $destination, array $config = []): void { /** @var FilesystemOperator $sourceFilesystem */ /* @var FilesystemOperator $destinationFilesystem */ [$sourceFilesystem, $sourcePath] = $this->determineFilesystemAndPath($source); [$destinationFilesystem, $destinationPath] = $this->determineFilesystemAndPath($destination); $sourceFilesystem === $destinationFilesystem ? $this->copyInSameFilesystem( $sourceFilesystem, $sourcePath, $destinationPath, $source, $destination ) : $this->copyAcrossFilesystem( $config['visibility'] ?? null, $sourceFilesystem, $sourcePath, $destinationFilesystem, $destinationPath, $source, $destination ); } public function publicUrl(string $path, array $config = []): string { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($path); if ( ! method_exists($filesystem, 'publicUrl')) { throw new UnableToGeneratePublicUrl(sprintf('%s does not support generating public urls.', $filesystem::class), $path); } return $filesystem->publicUrl($path, $config); } public function temporaryUrl(string $path, DateTimeInterface $expiresAt, array $config = []): string { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($path); if ( ! method_exists($filesystem, 'temporaryUrl')) { throw new UnableToGenerateTemporaryUrl(sprintf('%s does not support generating public urls.', $filesystem::class), $path); } return $filesystem->temporaryUrl($path, $expiresAt, $config); } public function checksum(string $path, array $config = []): string { /** @var FilesystemOperator $filesystem */ [$filesystem, $path] = $this->determineFilesystemAndPath($path); if ( ! method_exists($filesystem, 'checksum')) { throw new UnableToProvideChecksum(sprintf('%s does not support providing checksums.', $filesystem::class), $path); } return $filesystem->checksum($path, $config); } private function mountFilesystems(array $filesystems): void { foreach ($filesystems as $key => $filesystem) { $this->guardAgainstInvalidMount($key, $filesystem); /* @var string $key */ /* @var FilesystemOperator $filesystem */ $this->mountFilesystem($key, $filesystem); } } /** * @param mixed $key * @param mixed $filesystem */ private function guardAgainstInvalidMount($key, $filesystem): void { if ( ! is_string($key)) { throw UnableToMountFilesystem::becauseTheKeyIsNotValid($key); } if ( ! $filesystem instanceof FilesystemOperator) { throw UnableToMountFilesystem::becauseTheFilesystemWasNotValid($filesystem); } } private function mountFilesystem(string $key, FilesystemOperator $filesystem): void { $this->filesystems[$key] = $filesystem; } /** * @param string $path * * @return array{0:FilesystemOperator, 1:string} */ private function determineFilesystemAndPath(string $path): array { if (strpos($path, '://') < 1) { throw UnableToResolveFilesystemMount::becauseTheSeparatorIsMissing($path); } /** @var string $mountIdentifier */ /** @var string $mountPath */ [$mountIdentifier, $mountPath] = explode('://', $path, 2); if ( ! array_key_exists($mountIdentifier, $this->filesystems)) { throw UnableToResolveFilesystemMount::becauseTheMountWasNotRegistered($mountIdentifier); } return [$this->filesystems[$mountIdentifier], $mountPath, $mountIdentifier]; } private function copyInSameFilesystem( FilesystemOperator $sourceFilesystem, string $sourcePath, string $destinationPath, string $source, string $destination ): void { try { $sourceFilesystem->copy($sourcePath, $destinationPath); } catch (UnableToCopyFile $exception) { throw UnableToCopyFile::fromLocationTo($source, $destination, $exception); } } private function copyAcrossFilesystem( ?string $visibility, FilesystemOperator $sourceFilesystem, string $sourcePath, FilesystemOperator $destinationFilesystem, string $destinationPath, string $source, string $destination ): void { try { $visibility = $visibility ?? $sourceFilesystem->visibility($sourcePath); $stream = $sourceFilesystem->readStream($sourcePath); $destinationFilesystem->writeStream($destinationPath, $stream, compact('visibility')); } catch (UnableToRetrieveMetadata | UnableToReadFile | UnableToWriteFile $exception) { throw UnableToCopyFile::fromLocationTo($source, $destination, $exception); } } private function moveInTheSameFilesystem( FilesystemOperator $sourceFilesystem, string $sourcePath, string $destinationPath, string $source, string $destination ): void { try { $sourceFilesystem->move($sourcePath, $destinationPath); } catch (UnableToMoveFile $exception) { throw UnableToMoveFile::fromLocationTo($source, $destination, $exception); } } private function moveAcrossFilesystems(string $source, string $destination, array $config = []): void { try { $this->copy($source, $destination, $config); $this->delete($source); } catch (UnableToCopyFile | UnableToDeleteFile $exception) { throw UnableToMoveFile::fromLocationTo($source, $destination, $exception); } } } src/PathNormalizer.php 0000644 00000000224 15025032557 0011005 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; interface PathNormalizer { public function normalizePath(string $path): string; } src/FilesystemOperator.php 0000644 00000000212 15025032557 0011703 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; interface FilesystemOperator extends FilesystemReader, FilesystemWriter { } src/Visibility.php 0000644 00000000243 15025032557 0010176 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; final class Visibility { public const PUBLIC = 'public'; public const PRIVATE = 'private'; } src/WhitespacePathNormalizer.php 0000644 00000002210 15025032557 0013017 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; class WhitespacePathNormalizer implements PathNormalizer { public function normalizePath(string $path): string { $path = str_replace('\\', '/', $path); $this->rejectFunkyWhiteSpace($path); return $this->normalizeRelativePath($path); } private function rejectFunkyWhiteSpace(string $path): void { if (preg_match('#\p{C}+#u', $path)) { throw CorruptedPathDetected::forPath($path); } } private function normalizeRelativePath(string $path): string { $parts = []; foreach (explode('/', $path) as $part) { switch ($part) { case '': case '.': break; case '..': if (empty($parts)) { throw PathTraversalDetected::forPath($path); } array_pop($parts); break; default: $parts[] = $part; break; } } return implode('/', $parts); } } src/FileAttributes.php 0000644 00000005002 15025032557 0010773 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; class FileAttributes implements StorageAttributes { use ProxyArrayAccessToProperties; private string $type = StorageAttributes::TYPE_FILE; public function __construct( private string $path, private ?int $fileSize = null, private ?string $visibility = null, private ?int $lastModified = null, private ?string $mimeType = null, private array $extraMetadata = [] ) { $this->path = ltrim($this->path, '/'); } public function type(): string { return $this->type; } public function path(): string { return $this->path; } public function fileSize(): ?int { return $this->fileSize; } public function visibility(): ?string { return $this->visibility; } public function lastModified(): ?int { return $this->lastModified; } public function mimeType(): ?string { return $this->mimeType; } public function extraMetadata(): array { return $this->extraMetadata; } public function isFile(): bool { return true; } public function isDir(): bool { return false; } public function withPath(string $path): self { $clone = clone $this; $clone->path = $path; return $clone; } public static function fromArray(array $attributes): self { return new FileAttributes( $attributes[StorageAttributes::ATTRIBUTE_PATH], $attributes[StorageAttributes::ATTRIBUTE_FILE_SIZE] ?? null, $attributes[StorageAttributes::ATTRIBUTE_VISIBILITY] ?? null, $attributes[StorageAttributes::ATTRIBUTE_LAST_MODIFIED] ?? null, $attributes[StorageAttributes::ATTRIBUTE_MIME_TYPE] ?? null, $attributes[StorageAttributes::ATTRIBUTE_EXTRA_METADATA] ?? [] ); } public function jsonSerialize(): array { return [ StorageAttributes::ATTRIBUTE_TYPE => self::TYPE_FILE, StorageAttributes::ATTRIBUTE_PATH => $this->path, StorageAttributes::ATTRIBUTE_FILE_SIZE => $this->fileSize, StorageAttributes::ATTRIBUTE_VISIBILITY => $this->visibility, StorageAttributes::ATTRIBUTE_LAST_MODIFIED => $this->lastModified, StorageAttributes::ATTRIBUTE_MIME_TYPE => $this->mimeType, StorageAttributes::ATTRIBUTE_EXTRA_METADATA => $this->extraMetadata, ]; } } src/UnableToCheckDirectoryExistence.php 0000644 00000000401 15025032557 0014247 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; class UnableToCheckDirectoryExistence extends UnableToCheckExistence { public function operation(): string { return FilesystemOperationFailed::OPERATION_DIRECTORY_EXISTS; } } src/PathTraversalDetected.php 0000644 00000000742 15025032557 0012275 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; class PathTraversalDetected extends RuntimeException implements FilesystemException { private string $path; public function path(): string { return $this->path; } public static function forPath(string $path): PathTraversalDetected { $e = new PathTraversalDetected("Path traversal detected: {$path}"); $e->path = $path; return $e; } } src/FilesystemException.php 0000644 00000000202 15025032557 0012045 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use Throwable; interface FilesystemException extends Throwable { } src/UnableToProvideChecksum.php 0000644 00000000603 15025032557 0012574 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToProvideChecksum extends RuntimeException implements FilesystemException { public function __construct(string $reason, string $path, ?Throwable $previous = null) { parent::__construct("Unable to get checksum for $path: $reason", 0, $previous); } } src/InvalidVisibilityProvided.php 0000644 00000001051 15025032557 0013200 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use InvalidArgumentException; use function var_export; class InvalidVisibilityProvided extends InvalidArgumentException implements FilesystemException { public static function withVisibility(string $visibility, string $expectedMessage): InvalidVisibilityProvided { $provided = var_export($visibility, true); $message = "Invalid visibility provided. Expected {$expectedMessage}, received {$provided}"; throw new InvalidVisibilityProvided($message); } } src/ProxyArrayAccessToProperties.php 0000644 00000002315 15025032557 0013673 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; /** * @internal */ trait ProxyArrayAccessToProperties { private function formatPropertyName(string $offset): string { return str_replace('_', '', lcfirst(ucwords($offset, '_'))); } /** * @param mixed $offset * * @return bool */ public function offsetExists($offset): bool { $property = $this->formatPropertyName((string) $offset); return isset($this->{$property}); } /** * @param mixed $offset * * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($offset) { $property = $this->formatPropertyName((string) $offset); return $this->{$property}; } /** * @param mixed $offset * @param mixed $value */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value): void { throw new RuntimeException('Properties can not be manipulated'); } /** * @param mixed $offset */ #[\ReturnTypeWillChange] public function offsetUnset($offset): void { throw new RuntimeException('Properties can not be manipulated'); } } src/UnableToRetrieveMetadata.php 0000644 00000003746 15025032557 0012742 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToRetrieveMetadata extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $location; /** * @var string */ private $metadataType; /** * @var string */ private $reason; public static function lastModified(string $location, string $reason = '', Throwable $previous = null): self { return static::create($location, FileAttributes::ATTRIBUTE_LAST_MODIFIED, $reason, $previous); } public static function visibility(string $location, string $reason = '', Throwable $previous = null): self { return static::create($location, FileAttributes::ATTRIBUTE_VISIBILITY, $reason, $previous); } public static function fileSize(string $location, string $reason = '', Throwable $previous = null): self { return static::create($location, FileAttributes::ATTRIBUTE_FILE_SIZE, $reason, $previous); } public static function mimeType(string $location, string $reason = '', Throwable $previous = null): self { return static::create($location, FileAttributes::ATTRIBUTE_MIME_TYPE, $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); $e->reason = $reason; $e->location = $location; $e->metadataType = $type; return $e; } public function reason(): string { return $this->reason; } public function location(): string { return $this->location; } public function metadataType(): string { return $this->metadataType; } public function operation(): string { return FilesystemOperationFailed::OPERATION_RETRIEVE_METADATA; } } src/UnableToCreateDirectory.php 0000644 00000002516 15025032557 0012576 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToCreateDirectory extends RuntimeException implements FilesystemOperationFailed { private string $location; private string $reason = ''; public static function atLocation(string $dirname, string $errorMessage = '', ?Throwable $previous = null): UnableToCreateDirectory { $message = "Unable to create a directory at {$dirname}. {$errorMessage}"; $e = new static(rtrim($message), 0, $previous); $e->location = $dirname; $e->reason = $errorMessage; return $e; } public static function dueToFailure(string $dirname, Throwable $previous): UnableToCreateDirectory { $reason = $previous instanceof UnableToCreateDirectory ? $previous->reason() : ''; $message = "Unable to create a directory at $dirname. $reason"; $e = new static(rtrim($message), 0, $previous); $e->location = $dirname; $e->reason = $reason ?: $message; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_CREATE_DIRECTORY; } public function reason(): string { return $this->reason; } public function location(): string { return $this->location; } } src/UnableToDeleteFile.php 0000644 00000001632 15025032557 0011506 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToDeleteFile extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $location = ''; /** * @var string */ private $reason; public static function atLocation(string $location, string $reason = '', Throwable $previous = null): UnableToDeleteFile { $e = new static(rtrim("Unable to delete file located at: {$location}. {$reason}"), 0, $previous); $e->location = $location; $e->reason = $reason; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_DELETE; } public function reason(): string { return $this->reason; } public function location(): string { return $this->location; } } src/UnableToCopyFile.php 0000644 00000001704 15025032557 0011216 0 ustar 00 <?php declare(strict_types=1); namespace League\Flysystem; use RuntimeException; use Throwable; final class UnableToCopyFile extends RuntimeException implements FilesystemOperationFailed { /** * @var string */ private $source; /** * @var string */ private $destination; public function source(): string { return $this->source; } public function destination(): string { return $this->destination; } public static function fromLocationTo( string $sourcePath, string $destinationPath, Throwable $previous = null ): UnableToCopyFile { $e = new static("Unable to copy file from $sourcePath to $destinationPath", 0 , $previous); $e->source = $sourcePath; $e->destination = $destinationPath; return $e; } public function operation(): string { return FilesystemOperationFailed::OPERATION_COPY; } } LICENSE 0000644 00000002047 15025032557 0005560 0 ustar 00 Copyright (c) 2013-2023 Frank de Jonge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. INFO.md 0000644 00000000213 15025032557 0005621 0 ustar 00 View the docs at: https://flysystem.thephpleague.com/docs/ Changelog at: https://github.com/thephpleague/flysystem/blob/3.x/CHANGELOG.md .dockerignore 0000644 00000000005 15025032557 0007217 0 ustar 00 .git
| ver. 1.4 |
.
| PHP 8.1.32 | Generation time: 0 |
proxy
|
phpinfo
|
Settings