Showing preview only (790K chars total). Download the full file or copy to clipboard to get everything.
Repository: thephpleague/flysystem
Branch: 3.x
Commit: 254b1595b16b
Files: 293
Total size: 720.5 KB
Directory structure:
gitextract_99z1k6qe/
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── Bug.md
│ │ ├── Feature_Request.md
│ │ └── Question.md
│ ├── release.yml
│ ├── stale.yml
│ └── workflows/
│ ├── publish-subsplits.yml
│ ├── quality-assurance.yml
│ └── set-subsplit-default-branch.yml
├── .gitignore
├── .php-cs-fixer.dist.php
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── INFO.md
├── LICENSE
├── bin/
│ ├── .gitignore
│ ├── check-versions.php
│ ├── close-subsplit-prs.yml
│ ├── set-flysystem-version.php
│ ├── tools.php
│ └── update-subsplit-closers.php
├── composer.json
├── config.subsplit-publish.json
├── docker-compose.yml
├── mocked-functions.php
├── phpstan-baseline.neon
├── phpstan.neon
├── phpunit.php
├── phpunit.xml.dist
├── readme.md
├── src/
│ ├── AdapterTestUtilities/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ExceptionThrowingFilesystemAdapter.php
│ │ ├── FilesystemAdapterTestCase.php
│ │ ├── README.md
│ │ ├── RetryOnTestException.php
│ │ ├── ToxiproxyManagement.php
│ │ ├── composer.json
│ │ ├── test-functions.php
│ │ └── test_files/
│ │ └── unknown-mime-type.md5
│ ├── AsyncAwsS3/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── AsyncAwsS3Adapter.php
│ │ ├── AsyncAwsS3AdapterTest.php
│ │ ├── LICENSE
│ │ ├── PortableVisibilityConverter.php
│ │ ├── README.md
│ │ ├── S3ClientStub.php
│ │ ├── VisibilityConverter.php
│ │ └── composer.json
│ ├── AwsS3V3/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── AwsS3V3Adapter.php
│ │ ├── AwsS3V3AdapterTest.php
│ │ ├── LICENSE
│ │ ├── PortableVisibilityConverter.php
│ │ ├── README.md
│ │ ├── S3ClientStub.php
│ │ ├── VisibilityConverter.php
│ │ └── composer.json
│ ├── AzureBlobStorage/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── AzureBlobStorageAdapter.php
│ │ ├── AzureBlobStorageAdapterTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── composer.json
│ ├── CalculateChecksumFromStream.php
│ ├── ChecksumAlgoIsNotSupported.php
│ ├── ChecksumProvider.php
│ ├── Config.php
│ ├── ConfigTest.php
│ ├── CorruptedPathDetected.php
│ ├── DecoratedAdapter.php
│ ├── DirectoryAttributes.php
│ ├── DirectoryAttributesTest.php
│ ├── DirectoryListing.php
│ ├── DirectoryListingTest.php
│ ├── ExceptionInformationTest.php
│ ├── FileAttributes.php
│ ├── FileAttributesTest.php
│ ├── Filesystem.php
│ ├── FilesystemAdapter.php
│ ├── FilesystemException.php
│ ├── FilesystemOperationFailed.php
│ ├── FilesystemOperator.php
│ ├── FilesystemReader.php
│ ├── FilesystemTest.php
│ ├── FilesystemWriter.php
│ ├── Ftp/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ConnectionProvider.php
│ │ ├── ConnectivityChecker.php
│ │ ├── ConnectivityCheckerThatCanFail.php
│ │ ├── FtpAdapter.php
│ │ ├── FtpAdapterTest.php
│ │ ├── FtpAdapterTestCase.php
│ │ ├── FtpConnectionException.php
│ │ ├── FtpConnectionOptions.php
│ │ ├── FtpConnectionProvider.php
│ │ ├── FtpConnectionProviderTest.php
│ │ ├── FtpdAdapterTest.php
│ │ ├── InvalidListResponseReceived.php
│ │ ├── LICENSE
│ │ ├── NoopCommandConnectivityChecker.php
│ │ ├── NoopCommandConnectivityCheckerTest.php
│ │ ├── README.md
│ │ ├── RawListFtpConnectivityChecker.php
│ │ ├── RawListFtpConnectivityCheckerTest.php
│ │ ├── StubConnectionProvider.php
│ │ ├── UnableToAuthenticate.php
│ │ ├── UnableToConnectToFtpHost.php
│ │ ├── UnableToEnableUtf8Mode.php
│ │ ├── UnableToMakeConnectionPassive.php
│ │ ├── UnableToResolveConnectionRoot.php
│ │ ├── UnableToSetFtpOption.php
│ │ └── composer.json
│ ├── GoogleCloudStorage/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── GoogleCloudStorageAdapter.php
│ │ ├── GoogleCloudStorageAdapterTest.php
│ │ ├── GoogleCloudStorageAdapterWithoutAclTest.php
│ │ ├── LICENSE
│ │ ├── PortableVisibilityHandler.php
│ │ ├── README.md
│ │ ├── StubRiggedBucket.php
│ │ ├── StubStorageClient.php
│ │ ├── UniformBucketLevelAccessVisibility.php
│ │ ├── VisibilityHandler.php
│ │ └── composer.json
│ ├── GridFS/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── GridFSAdapter.php
│ │ ├── GridFSAdapterTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── composer.json
│ ├── InMemory/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── InMemoryFile.php
│ │ ├── InMemoryFilesystemAdapter.php
│ │ ├── InMemoryFilesystemAdapterTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── StaticInMemoryAdapterRegistry.php
│ │ ├── StaticInMemoryAdapterRegistryTest.php
│ │ └── composer.json
│ ├── InvalidStreamProvided.php
│ ├── InvalidVisibilityProvided.php
│ ├── Local/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── FallbackMimeTypeDetector.php
│ │ ├── LICENSE
│ │ ├── LocalFilesystemAdapter.php
│ │ ├── LocalFilesystemAdapterTest.php
│ │ ├── README.md
│ │ └── composer.json
│ ├── MountManager.php
│ ├── MountManagerTest.php
│ ├── PathNormalizer.php
│ ├── PathPrefixer.php
│ ├── PathPrefixerTest.php
│ ├── PathPrefixing/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── LICENSE
│ │ ├── PathPrefixedAdapter.php
│ │ ├── PathPrefixedAdapterTest.php
│ │ ├── README.md
│ │ └── composer.json
│ ├── PathTraversalDetected.php
│ ├── PhpseclibV2/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ConnectionProvider.php
│ │ ├── ConnectivityChecker.php
│ │ ├── FixatedConnectivityChecker.php
│ │ ├── README.md
│ │ ├── SftpAdapter.php
│ │ ├── SftpAdapterTest.php
│ │ ├── SftpConnectionProvider.php
│ │ ├── SftpConnectionProviderTest.php
│ │ ├── SftpStub.php
│ │ ├── SimpleConnectivityChecker.php
│ │ ├── StubSftpConnectionProvider.php
│ │ ├── UnableToAuthenticate.php
│ │ ├── UnableToConnectToSftpHost.php
│ │ ├── UnableToEstablishAuthenticityOfHost.php
│ │ ├── UnableToLoadPrivateKey.php
│ │ └── composer.json
│ ├── PhpseclibV3/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ConnectionProvider.php
│ │ ├── ConnectivityChecker.php
│ │ ├── FixatedConnectivityChecker.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── SftpAdapter.php
│ │ ├── SftpAdapterTest.php
│ │ ├── SftpConnectionProvider.php
│ │ ├── SftpConnectionProviderTest.php
│ │ ├── SftpStub.php
│ │ ├── SimpleConnectivityChecker.php
│ │ ├── StubSftpConnectionProvider.php
│ │ ├── UnableToAuthenticate.php
│ │ ├── UnableToConnectToSftpHost.php
│ │ ├── UnableToEstablishAuthenticityOfHost.php
│ │ ├── UnableToLoadPrivateKey.php
│ │ └── composer.json
│ ├── PortableVisibilityGuard.php
│ ├── ProxyArrayAccessToProperties.php
│ ├── ReadOnly/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── ReadOnlyFilesystemAdapter.php
│ │ ├── ReadOnlyFilesystemAdapterTest.php
│ │ └── composer.json
│ ├── ResolveIdenticalPathConflict.php
│ ├── StorageAttributes.php
│ ├── SymbolicLinkEncountered.php
│ ├── UnableToCheckDirectoryExistence.php
│ ├── UnableToCheckExistence.php
│ ├── UnableToCheckFileExistence.php
│ ├── UnableToCopyFile.php
│ ├── UnableToCreateDirectory.php
│ ├── UnableToDeleteDirectory.php
│ ├── UnableToDeleteFile.php
│ ├── UnableToGeneratePublicUrl.php
│ ├── UnableToGenerateTemporaryUrl.php
│ ├── UnableToListContents.php
│ ├── UnableToMountFilesystem.php
│ ├── UnableToMoveFile.php
│ ├── UnableToProvideChecksum.php
│ ├── UnableToReadFile.php
│ ├── UnableToResolveFilesystemMount.php
│ ├── UnableToRetrieveMetadata.php
│ ├── UnableToSetVisibility.php
│ ├── UnableToWriteFile.php
│ ├── UnixVisibility/
│ │ ├── PortableVisibilityConverter.php
│ │ ├── PortableVisibilityConverterTest.php
│ │ └── VisibilityConverter.php
│ ├── UnreadableFileEncountered.php
│ ├── UrlGeneration/
│ │ ├── ChainedPublicUrlGenerator.php
│ │ ├── ChainedPublicUrlGeneratorTest.php
│ │ ├── PrefixPublicUrlGenerator.php
│ │ ├── PublicUrlGenerator.php
│ │ ├── ShardedPrefixPublicUrlGenerator.php
│ │ └── TemporaryUrlGenerator.php
│ ├── Visibility.php
│ ├── WebDAV/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ByteMarkWebDAVServerTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── SabreServerTest.php
│ │ ├── UrlPrefixingClientStub.php
│ │ ├── WebDAVAdapter.php
│ │ ├── WebDAVAdapterTestCase.php
│ │ ├── composer.json
│ │ └── resources/
│ │ ├── .gitignore
│ │ └── server.php
│ ├── WhitespacePathNormalizer.php
│ ├── WhitespacePathNormalizerTest.php
│ └── ZipArchive/
│ ├── .gitattributes
│ ├── .github/
│ │ └── workflows/
│ │ └── close-subsplit-prs.yaml
│ ├── FilesystemZipArchiveProvider.php
│ ├── LICENSE
│ ├── NoRootPrefixZipArchiveAdapterTest.php
│ ├── PrefixedRootZipArchiveAdapterTest.php
│ ├── README.md
│ ├── StubZipArchive.php
│ ├── StubZipArchiveProvider.php
│ ├── UnableToCreateParentDirectory.php
│ ├── UnableToOpenZipArchive.php
│ ├── ZipArchiveAdapter.php
│ ├── ZipArchiveAdapterTestCase.php
│ ├── ZipArchiveException.php
│ ├── ZipArchiveProvider.php
│ └── composer.json
└── test_files/
├── .gitignore
├── sftp/
│ ├── id_rsa
│ ├── id_rsa.pub
│ ├── ssh_host_ed25519_key
│ ├── ssh_host_ed25519_key.pub
│ ├── ssh_host_rsa_key
│ ├── ssh_host_rsa_key.pub
│ ├── sshd_custom_configs.sh
│ ├── unknown.key
│ └── users.conf
├── toxiproxy/
│ └── toxiproxy.json
├── wait_for_ftp.php
└── wait_for_sftp.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
.git
================================================
FILE: .editorconfig
================================================
[*]
indent_style = space
[*.yml]
indent_size = 2
[composer.json]
indent_size = 4
[*.php]
end_of_line = lf
insert_final_newline = true
================================================
FILE: .gitattributes
================================================
* text=auto
/.docker export-ignore
/.dockerignore export-ignore
/docker-compose.yml export-ignore
/config.subsplit-publish.json export-ignore
/.editorconfig export-ignore
/.php-cs-fixer.dist.php export-ignore
/phpstan.neon export-ignore
/phpstan-baseline.neon export-ignore
/phpunit.php export-ignore
/phpunit.xml.dist export-ignore
/.travis.yml export-ignore
/.scrutinizer.yml export-ignore
/CHANGELOG.md export-ignore
/CODE_OF_CONDUCT.md export-ignore
/deprecations.md export-ignore
/docker-composer.yml export-ignore
/README.md export-ignore
/CODE_OF_CONDUCT.md export-ignore
/.github export-ignore
/src/AsyncAwsS3 export-ignore
/src/AwsS3V3 export-ignore
/src/GoogleCloudStorage export-ignore
/src/Ftp export-ignore
/src/InMemory export-ignore
/src/PhpseclibV2 export-ignore
/src/PhpseclibV3 export-ignore
/src/AdapterTestUtilities export-ignore
/src/AzureBlobStorage export-ignore
/src/ZipArchive export-ignore
/src/WebDAV export-ignore
/src/PathPrefixing export-ignore
/src/Local export-ignore
/src/ReadOnly export-ignore
/src/GridFS export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/bin/ export-ignore
/mocked-functions.php export-ignore
/test_files/ export-ignore
/**/*Test.php export-ignore
/**/*Stub.php export-ignore
/**/Stub*.php export-ignore
================================================
FILE: .github/ISSUE_TEMPLATE/Bug.md
================================================
---
name: 🐛 Bug
about: Did you encounter a bug?
---
### Bug Report
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A |
|-------------------|---------|
| Flysystem Version | x.y.z |
| Adapter Name | example |
| Adapter version | x.y.z |
#### Summary
<!-- Provide a summary describing the problem you are experiencing. -->
#### How to reproduce
<!--
Provide steps to reproduce the issue.
If possible, also add a code snippet.
-->
================================================
FILE: .github/ISSUE_TEMPLATE/Feature_Request.md
================================================
---
name: 🎉 Feature Request
about: Do you have a new feature in mind?
---
### Feature Request
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A |
|-------------------|---------|
| Flysystem Version | x.y.z |
| Adapter Name | example |
| Adapter version | x.y.z |
#### Scenario / Use-case
<!-- Provide an explain in which scenario the feature would be helpful. -->
#### Summary
<!-- Provide a summary of the feature you would like to see implemented. -->
================================================
FILE: .github/ISSUE_TEMPLATE/Question.md
================================================
---
name: ❓ Question
about: Are you unsure about something?
---
### Question
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A |
|-------------------|---------|
| Flysystem Version | x.y.z |
| Adapter Name | example |
| Adapter version | x.y.z |
================================================
FILE: .github/release.yml
================================================
changelog:
categories:
- title: Breaking Changes 🛠
labels:
- Semver-Major
- breaking-change
- title: Exciting New Features 🎉
labels:
- Semver-Minor
- enhancement
- title: Other Changes
labels:
- "*"
================================================
FILE: .github/stale.yml
================================================
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- keep open
- 2.0 ideas
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
================================================
FILE: .github/workflows/publish-subsplits.yml
================================================
---
name: Sub-Split Publishing
on:
push:
branches:
- 3.x
create:
tags:
- '3.*'
delete:
tags:
- '3.*'
jobs:
publish_subsplits:
runs-on: ubuntu-latest
name: Publish package sub-splits
steps:
- uses: actions/checkout@v4
with:
fetch-depth: '0'
persist-credentials: 'false'
- uses: frankdejonge/use-github-token@1.1.0
with:
authentication: 'frankdejonge:${{ secrets.PERSONAL_ACCESS_TOKEN }}'
user_name: 'Frank de Jonge'
user_email: 'info@frenky.net'
- name: Cache splitsh-lite
id: splitsh-cache
uses: actions/cache@v4
with:
path: './.splitsh'
key: '${{ runner.os }}-splitsh'
- uses: frankdejonge/use-subsplit-publish@1.1.0
with:
source-branch: '3.x'
config-path: './config.subsplit-publish.json'
splitsh-path: './.splitsh/splitsh-lite'
splitsh-version: 'v1.0.1'
================================================
FILE: .github/workflows/quality-assurance.yml
================================================
---
name: Quality Assurance
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
on:
push:
paths:
- src/**/*.php
- .github/workflows/quality-assurance.yml
branches:
- 3.x
- 4.x
pull_request:
paths:
- src/**/*.php
- .github/workflows/quality-assurance.yml
branches:
- 3.x
- 4.x
schedule:
- cron: "5 1 * * *"
env:
FLYSYSTEM_AWS_S3_KEY: '${{ secrets.FLYSYSTEM_AWS_S3_KEY }}'
FLYSYSTEM_AWS_S3_SECRET: '${{ secrets.FLYSYSTEM_AWS_S3_SECRET }}'
FLYSYSTEM_AWS_S3_BUCKET: '${{ secrets.FLYSYSTEM_AWS_S3_BUCKET }}'
MONGODB_URI: 'mongodb://127.0.0.1:27017/'
FLYSYSTEM_TEST_DANGEROUS_THINGS: "yes"
FLYSYSTEM_TEST_SFTP: "yes"
jobs:
phpunit:
name: PHPUnit tests on ${{ matrix.php }} ${{ matrix.composer-flags }}
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
php: [ '8.2', '8.3', '8.4', '8.5' ]
composer-flags: [ '' ]
experimental: [false]
phpstan: [true]
phpunit-flags: [ '--coverage-text' ]
# include:
# - php: '8.2'
# experimental: false
# phpstan: false
# phpunit-flags: '--no-coverage'
# - php: '8.3'
# experimental: false
# phpstan: false
# phpunit-flags: '--no-coverage'
# - php: '8.4'
# experimental: false
# phpstan: false
# phpunit-flags: '--no-coverage'
steps:
- uses: actions/checkout@v4
- run: docker compose -f docker-compose.yml up -d
- name: Start an SSH Agent
uses: frankdejonge/use-ssh-agent@1.1.0
- run: chmod 0400 ./test_files/sftp/id_*
- id: ssh_agent
run: ssh-add ./test_files/sftp/id_rsa
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mongodb
coverage: pcov
tools: composer:v2
- run: composer update --no-progress ${{ matrix.composer-flags }}
- run: php test_files/wait_for_sftp.php
- run: php test_files/wait_for_ftp.php 2121
- run: php test_files/wait_for_ftp.php 2122
- run: COMPOSER_OPTS='${{ matrix.composer-flags }}' vendor/bin/phpunit ${{ matrix.phpunit-flags }}
- run: vendor/bin/phpstan analyse
if: ${{ matrix.phpstan }}
- run: vendor/bin/php-cs-fixer fix --diff --dry-run
continue-on-error: true
if: ${{ matrix.php == '8.0' }}
================================================
FILE: .github/workflows/set-subsplit-default-branch.yml
================================================
---
name: Update default sub-split branch
on: workflow_dispatch
jobs:
set-default-branch:
name: Set default git branch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: '0'
persist-credentials: 'false'
- uses: actions/github-script@v7
with:
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
script: |
const fs = require('fs');
let splits = JSON.parse(fs.readFileSync('config.subsplit-publish.json'))['sub-splits'];
for (let split of splits) {
const { groups: { repo } } = /git@github\.com:thephpleague\/(?<repo>.*)\.git/.exec(split.target);
console.log(`Found repo ${repo}`);
await github.rest.repos.update({
owner: 'thephpleague',
repo,
default_branch: '3.x',
});
}
================================================
FILE: .gitignore
================================================
/vendor/
/coverage/
/.phpunit.result.cache
/phpunit.xml
/composer.lock
/index_*.php
/.php-cs-fixer.php
/.php-cs-fixer.cache
/google-cloud-service-account.json
.idea
================================================
FILE: .php-cs-fixer.dist.php
================================================
<?php
$finder = PhpCsFixer\Finder::create()
->in([__DIR__ . '/'])
->exclude(__DIR__ . '/vendor');
return (new PhpCsFixer\Config())
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => true,
'single_line_after_imports' => true,
'blank_line_before_statement' => ['statements' => ['return']],
'cast_spaces' => true,
'concat_space' => ['spacing' => 'one'],
'no_singleline_whitespace_before_semicolons' => true,
'not_operator_with_space' => true,
'no_unused_imports' => true,
'phpdoc_align' => false,
'phpdoc_indent' => true,
'phpdoc_no_access' => true,
'phpdoc_no_alias_tag' => true,
'phpdoc_no_package' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_summary' => true,
'phpdoc_to_comment' => true,
'phpdoc_trim' => true,
'single_blank_line_at_eof' => true,
'ternary_operator_spaces' => true,
'ordered_imports' => [
'sort_algorithm' => 'alpha',
'imports_order' => ['const', 'class', 'function'],
],
'no_extra_blank_lines' => true,
'no_whitespace_in_blank_line' => true,
'nullable_type_declaration_for_default_null_value' => true,
])
->setFinder($finder);
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## 3.32.0 - 2026-02-25
### Changes
- [AwsS3V3] Allow SSE-C options when fetching file metadata
## 3.31.0 - 2026-01-23
### Changes
- [AsyncAwsS3] Allow V3
## 3.30.2 - 2025-11-10
### Fixes
- [Local] Clear last error for rename and copy operations (#1883)
## 3.30.1 - 2025-10-20
### Fixes
- Ensure listing directories called "0" do not produce unfiltered listings.
## 3.30.0 - 2025-06-25
### Changes
- [MongoDB] Allow v2
- [AsyncAWS] Encode/decode object identifiers
- [GoogleCloudStorage] Add option to stream responses
- [Local] Clear stat cache consistently
- [SFTP] Add option to disconnect connections on destruction
- [WebDAV] Deal with 405 case when trying to create a directory that already exists.
## 3.29.1 - 2024-10-08
### Fixes
- Normalise path for checksum call
## 3.29.0 - 2024-09-29
### Changes
- [FTP] Add error context from error messages
- [SFTP] overwrite on move
- [AWS S3] same path copy/move no-op
- [Async S3] transform error to flysystem errors
## 3.28.0 - 2024-05-22
### Added
- MongoDB GridFS adapter (by @GromNaN)
### Fixed
- PHP 8.3 directory listing issue for the FTP adapter (by @lanz1)
## 3.27.0 - 2024-04-07
### Fixed
- Corrected AWS SSE-C Options
- Handle MetadataDirective gracefully.
## 3.26.0 - 2024-03-25
### Fixed
- Make SFTP connectivity pinging an opt-in feature.
### Added
- Add `add_content_md5` option to AWS S3 (#1774)
- Added AWS SSE-C options (#1773)
## 3.25.1 - 2024-03-16
### Fixed
- Cleanup connection instance after disconnecting SFTP connection.
- Fix upcoming PHP 8.4 deprecations (#1772)
## 3.25.0 - 2024-03-09
### Added
- [MountManager] added ability to (dangerously) mount additional filesystems
- [FTP] added `disconnect` method to proactively close connections
- [SFTP V3] added `disconnect` method to proactively close connections
## 3.24.0 - 2024-02-04
### Fixes
- Updated method signatures to match upgraded dependency signatures for overrides (#1748, #1746)
- Added missing path prefixing in FTP implementation (#1747)
### Changes
- Updated string assertions to use PHP 8 functions (#1750, #1749))
## 3.23.1 - 2024-01-26
### Changes
- Updated license year
## 3.23.0 - 2023-12-04
### Fixed
- Fixed upstream regression caused by resolving inconclusive mime-type.
### Added
- Made inconclusive mime-type resolving configurable on the local adapter.
## 3.22.0 - 2023-12-03
### Changes
- Prevent double directory creation with lazy root creation for Local filesystem.
### Fixes
- Resolve to "inconclusive" mimetype instead of causing a type error by @GuySartorelli
- Corrected spelling of a configuration key for the Azure adapter by @shineability
### Additions
- MountManager::extend allows for immutable dynamic extension of the mount manager.
- Added a new abstract DecoratedAdapter for easier decoration of adapters by @jnoordsij
## 3.21.0 - 2023-11-18
### Changes
- Retain visibility on local copy for local FS, in line with other adapter (#1730) by @jnoordsij
## 3.20.0 - 2023-11-14
### Changed
- Normalise paths for public and temporary URLs (#1727)
## 3.19.0 - 2023-11-07
### Added
- Configuration option to specify if visibility should be retained during copy/move operations
- InMemoryFilesystemAdapter now supports visibility changes on move and copy.
- Default visibility options are ignored when moving/copying while respecting visibility retention settings.
- Local filesystem implementation now allows setting visibility on move and copy.
## 3.18.0 - 2023-10-05
### Added
- Configuration option to specify how to handle same path copy/move operations (#1715)
## 3.17.0 - 2023-10-05
### Added
- [AsyncAWS] Added support for version 2.0 of async-aws/{s3,simple-s3}
## 3.16.0 - 2023-09-07
### Added
- [AsyncAws] Allow specifying `get_object_options` for temporary URL generation
### Fixed
- [ZipArchive] override on move
- [WebDAV] encode path for propfind actions
- [PathPrefixing] [#1686](https://github.com/thephpleague/flysystem/issues/1686)
## 3.15.1 - 2023-05-04
### Fixed
- Remove duplicate class caused by package extractin and inclusion
## 3.15.0 - 2023-05-04
### Added
- Extracted the local adapter as a standalone package
### Changed
- Removed readme's from shipped artefacts.
## 3.14.0 - 2023-04-11
### Added
- Made disabling stat cache configurable for SFTP adapters.
## 3.13.0 - 2023-04-11
### Fixed
- AsyncAwsS3 object deletion now chunks per 100 objects to prevent memory exhaustion
- AsyncAwsS3 now disregards top-level directories from listings
- LocalAdapter now deals with file deletions during directory listings gracefully.
### Added
- DirectoryListing now supports correct phpstan for map and filter methods.
- FTP/SFTP added config option to detect the mime-type using the path alone (prevents a read)
- SFTP now supports PuTTY style private keys
-
## 3.12.3 - 2023-02-18
### Fixed
- [Google Cloud Storage] Fixed ACL error for uniform bucker ACL copy operations.
-
- ## 3.12.2 - 2023-01-19
### Fixed
- [AWS S3] Corrected param order for doesObjectExistV2 call
## 3.12.1 - 2023-01-06
### Fixed
- [AWS S3] Use doesObjectExistV2 to prevent false positive respomnses.
## 3.12.0 - 2022-12-20
### Added
- [Core] Chained public URL generation strategy
### Fixed
- [WebDAV] Handle cases where the content listing returns entries with URL prefixes.
- [Local] Ensure correct implicit root creations happens on windows.
- [ZipArchive] Fix incorrect zip contents listing for top-level directory.
## 3.11.0 - 2022-12-02
### Added
- [Google Cloud Storage] Added `UniformBucketLevelAccessVisibility` to allow buckets with uniform bucket-level access policies.
## 3.10.4 - 2022-11-26
### Changed
- [I became a dad, meet Tim](https://twitter.com/frankdejonge/status/1594966175108177921)
### Fixed
- [PathPrefixing] ensure `checksum` and `temporaryUrl` are prefixed
- [WebDAV] ensure directory creation uses trailing slashes for paths
## 3.10.3 - 2022-11-14
### Fixed
- [Local] Handle checksum errors without message (#1590)
## 3.10.2 - 2022-10-25
### Fixed
- [Filesystem] Ensure adapter is used for exposing temporary URLs.
## 3.10.1 - 2022-10-21
### Fixed
- [Filesystem] Added missing constructor argument to allow temporary URL generator injection.
## 3.10.0 - 2022-10-21
### Added
- [Filesystem] added `temporaryUrl` method
- [AsyncAWS] added `temporaryUrl` method
- [AWS S3] added `temporaryUrl` method
- [Azure Blob Storage] added `temporaryUrl` method
- [MountManager] added `temporaryUrl` method
- [Google Cloud Storage] added `temporaryUrl` method
- [ReadOnly] added `temporaryUrl` method
- [PathPrefixing] added `temporaryUrl` method
## 3.9.0 - 2022-10-18
### Added
- [Filesystem] Added ability to inject custom public URL generator into a filesystem.
- [MountManager] added `checksum` and `publicUrl` methods
- [ZipArchive] Do not prefix directories when creating/reading an archive
- [ShardedPrefixPublicUrlGenerator] added url generator strategy that distributes over a list of prefixes
## 3.8.0 - 2022-10-18
### Added
- [ChecksumAlgoIsNotSupported] Exception to indicate a checksum is not supported by the checksum provider, filesystem will fall back to ad-hoc generation.
## 3.7.0 - 2022-10-17
### Added
- [Filesystem] added `checksum` method
- [AWS S3] added `checksum` method
- [Async S3] added `checksum` method
- [Google Cloud Storage] added `checksum` method
- [Azure Blob Storage] added `checksum` method
## 3.6.0 - 2022-10-13
### Added
- [Filesystem] Added public url method
- [Azure Blob Storage] Added public url method
- [AWS S3] Added public url method
- [Async S3] Added public url method
- [GCS] Added public url method
- [WebDAV] Added public url method
- [ReadOnly] Added public url method
- [PathPrefixing] Added public url method
## 3.5.3 - 2022-09-23
### Fixed
- [SFTP] Account for missing "type" field in metadata result.
## 3.5.2 - 2022-09-23
### Fixed
- [SFTP v2/v3] Fixed possible race-condition during directory creation leading to false failures.
## 3.5.1 - 2022-09-18
### Fixed
- [WebDAV] Strip directory prefix in `createDirectory` to prevent double prefixing in `directoryExists`.
## 3.5.0 - 2022-09-17
### Added
- [AWS S3] Allow specifying visibility on move and copy
## 3.4.0 - 2022-09-15
### Added
- Added FTP configuration option useRawListOptions (null|false|true).
- UnableToListContents exception was added to uniformly represent content listing exceptions.
### Fixed
- [FTP] Don't use raw list options for FileZilla FTP servers ([#1553](https://github.com/thephpleague/flysystem/pull/1553))
- [WebDAV] Correct path formatting for move and copy operations ([#1552](https://github.com/thephpleague/flysystem/pull/1552))
## 3.3.0 - 2022-09-09
### Added
- StaticInMemoryAdapterRegistry contributed by @kbond
- ReadonlyFilesystemAdapter contributed by @kbond
- PathPrefixedAdapter contributed by @shyim
### Fixed
- WebDAV prefix is now encoded and the dir is not required to be pre-created ([#1533](https://github.com/thephpleague/flysystem/pull/1533))
## 3.2.1 - 2022-08-14
### Fixed
- [ZipArchive] reverted regression introduced in [#1525](https://github.com/thephpleague/flysystem/pull/1525)
## 3.2.0 - 2022-07-26
### Added
- [AwsS3V3] Added configuration options for forwarded options, multipart upload configuration, and metadata fields.
### Fixes
- [ZipArchive] delete top-level directory when deleting directories.
- [AwsS3V3] add `ChecksumAlgorithm` to forwarded options.
- [AwsS3V3] add `ContentMD5` to forwarded options.
- [AwsS3V3] made forwarded options and metadata fields configurable.
- [SftpV3] upgrade minimum version, PHP 8 and the lowest version fails to authenticate.
## 3.1.1 - 2022-07-18
- [AwsS3V3] Corrected exception type (#1524)
## 3.1.0 - 2022-06-29
- Added option for the Local adapter to create the root directory only on the first mutating (write/copy/move) action.
## 3.0.23 - 2022-06-29
- Added reasons for exceptions for all adapters that were missing previous exception messages.
## 3.0.22 - 2022-06-29
- [AwsS3V3] Added reasons for exceptions
- [AwsS3V3] Use ListObjectsV2 instead of ListObjects
## 3.0.21 - 2022-06-12
- [AwsS3V3] Use ListObjectsV2 instead of ListObjects
## 3.0.20 - 2022-05-25
### Fixed
- [Core] Fix deprecated ${var} string interpolation patterns (#1470)
## 3.0.19 - 2022-05-03
### Fixed
- [FTP] Turn errors into proper exceptions when resolving the connection root (#1460)
## 3.0.18 - 2022-04-25
### Fixed
- [SFTP v3] Fix retries (#1451)
## 3.0.17 - 2022-04-14
### Fixed
- [SFTP v2] Avoid type errors when public key is not retrieved (#1446)
- [SFTP v3] Avoid type errors when public key is not retrieved (#1446)
## 3.0.16 - 2022-04-11
### Fixed
- [Local] fall back to extension lookups when the mime-type comes up as inconclusive.
## 3.0.15 - 2022-04-08
### Fixed
- [GCS] Allow setting upload metadata
- [GCS] Allow setting contentType, or resolve it
- [SFTP v2+v3] Delete top-level directory too.
## 3.0.14 - 2022-04-06
### Added
- [InMemory] allow to set a last-updated time (#1438)
- [SFTP V3] allow configuring preferred algo's (#1440)
## 3.0.13 - 2022-04-02
### Fixed
- [AWS S3 V3] Do not return top-level directory when listing that same directory
## 3.0.12 - 2022-03-12
### Fixed
- [SFTP V3] Fix issue where listing is false.
- [Async AWS S3] Cosmetic fix for directory prefixing.
## 3.0.11 - 2022-03-04
### Fixed
- [AWS S3] Use globally configured options.
## 3.0.10 - 2022-02-26
### Fixed
- [AWS S3] fix detecting directories that only contain other directories but no files.
- [AWS S3] when checking for directory existence, limit the result set (perf)
- [AWS S3] throw interface exception when failing to delete directory
- [Async AWS S3] when checking for directory existence, limit the result set (perf)
## 3.0.9 - 2022-02-22
### Fixed
- [AWS S3] support setting an ACL as a direct option instead of using visibility.
## 3.0.8 - 2022-02-16
### Fixed
- [AWS S3] Set ContentType when mime-type config option is set during writes, like in v1.
## 3.0.7 - 2022-02-14
### Fixed
- [WebDAV] added missing composer.json for sub-split
## 3.0.6 - 2022-02-14
### Added
- [WebDAV] new adapter added
### Fixed
- [Core] Trim slashed uniformly in the attribute classes.
- [Core] Uniformly use directory_visibility over visibility for directory usage.
- [FTP] export-ignore the test case.
## 3.0.5 - 2022-02-12
### Added
- [AzureBlobStorage] New adapter added
### Fixed
- [AsyncAwsS3] Make EXTRA_METADATA_FIELDS protected to prevent error when extending the class
## 3.0.4 - 2022-02-10
### Fixed
- [FTP] Do not require setting of the root directory, use '' by default.
## 3.0.3 - 2022-01-31
### Fixed
- [FTP] Made connection resolving lazy again (#1414)
## 3.0.2 - 2022-01-30
### Fixes
* [FTP] Support relative or empty connection root directories (#1410)
## 3.0.1 - 2022-01-15
### Fixes
* [ZipArchive] delete top-level directory too when deleting a directory
* [GoogleCloudStorage] Use listing to check for directory existence (consistency)
* [GoogleCloudStorage] Fixed bug where exceptions were not thrown
* [AwsS3V3] Allow passing options for controlling multi-upload options (#1396)
* [Local] Convert windows-style directory separator to unix-style (#1398)
## 3.0.0 - 2022-01-13
### Added
* FilesystemReader::has to check for directory or file existence
* FilesystemReader::directoryExists to check for directory existence
* FilesystemReader::fileExists to check for file existence
* FilesystemAdapter::directoryExists to check for directory existence
* FilesystemAdapter::fileExists to check for file existence
## 2.5.0 - 2022-09-17
### Added
- [AWS S3] Allow specifying visibility on move and copy
## 2.4.5 - 2022-04-25
- [SFTP v3] Fix retries (#1451)
## 2.4.4 - 2022-04-14
### Fixed
- [SFTP v2] Avoid type errors when public key is not retrieved (#1446)
- [SFTP v3] Avoid type errors when public key is not retrieved (#1446)
## 2.4.3 - 2022-02-16
### Fixed
- [AWS S3] Set ContentType when mime-type config option is set during writes, like in v1.
## 2.4.2 - 2022-01-31
### Fixed
- [FTP] Made connection resolving lazy again (#1414)
## 2.4.1 - 2022-01-30
### Fixed
- [FTP] Fix relative connection root handling
## 2.4.0 - 2022-01-04
### Added
- [SFTP V3] New adapter officially published
## 2.3.2 - 2021-11-28
### Fixed
- [FTP] Check for FTP\Connection object in addition to a `resource` for connectivity checks and connection handling.
- [Local] Simplify writeStream, as a bonus, have an EXT_LOCK on it now by default.
## 2.3.1 - 2021-09-22
### Fixed
- [ZipArchive] copy stream, the ziparchive is closed after getting the stream
- [Core] PHP 8.1 compatibility updates
- [LocalFilesystem] parse permissions during listing
- [LocalFilesystem] clear realstatcache
- [FTP] PHP 8.1 compatibility updates
- [Core] Upgraded PHP-CS-Fixer
## 2.3.0 - 2021-09-22
### Added
- [GoogleCloudStorage] Make it possible to set an empty prefix (#1358)
- [GoogleCloudStorage] Added possibility not to set visibility (#1356)
## 2.2.3 - 2021-08-18
### Fixed
- [Core] Corrected exception message for UnableToCopyFile.
## 2.2.2 - 2021-08-18
### Fixed
- [Core] Ensure the sorted directory listing can be iterated over (#1342).
## 2.2.1 - 2021-08-17
### Fixed
- [FTP] use original path when ensuring the parent directory exists during `move` operation.
- [FTP] do not fail setting UTF-8 when the server is already on UTF-8.
## 2.2.0 - 2021-07-20
### Added
* [Core] Added sortByPath on the directory listing to allows content listings to be sorted.
## 2.1.1 - 2021-06-24
### Fixed
* [Core] Whitespace normalization now no longer strips funky whitespace but throws an exception.
## 2.1.0 - 2021-05-25
### Added
* [Core] the DirectoryAttributes now have an `extraMetadata` like files do.
### Fixed
* [AwsS3V3] Allow the ACL config option to take precedence over the visibility key.
## 2.0.8 - 2021-05-15
### Fixed
* [SFTP] Don't fail listing contents when a directory does not exist (#1301)
## 2.0.7 - 2021-05-13
### Fixed
* [LocalFilesystem] convert windows style paths to unix style paths on listing
## 2.0.6 - 2021-05-13
### Fixed
* [AsyncAwsS3] do not urlencode CopySource arguments (#1302)
## 2.0.5 - 2021-04-11
### Fixed
* [AwsS3] ensure write errors are turned into exceptions.
## 2.0.4 - 2021-02-13
### Fixed
* [InMemory] Corrected how the file size is determined.
## 2.0.3 - 2021-02-09
### Fixed
* [AwsS3V3] Use the $config array during the copy operation.
* [Ftp] Close FTP connections when the object is destructed.
* [Core] Allow for an absolute root path of `/`.
## 2.0.2 - 2020-12-28
### Fixed
* Corrected the ignored exports for Ftp
## 2.0.1 - 2020-12-28
### Fixed
* Corrected the ignored exports for Phpseclib
## 2.0.0 - 2020-11-24
### Changed
- string type added to all visibility input
### Added
- Google Cloud Storage adapter.
## 2.0.0-beta.3 - 2020-08-23
### Added
- UnableToCheckFileExistence error introduced
- Mount manager is re-introduced
### Fixes
- Allow FTP filenames to contain special characters.
- Prevent resources of incorrect types to be passed.
### Improved
- [AWS] By default, make sure readStream resources are streamed over HTTP.
### Added
- DirectoryAttributes now have a `lastModified` accessor.
## 2.0.0-beta.2 - 2020-08-08
### Fixes
- Allow listing of top-level directory for AWS S3
- Ensure the adapters can use the correct beta release.
## 2.0.0-beta.1 - 2020-08-04
### Changes
- Small code optimizations
- Add global options array to AwsS3V3Adapter like in V1
## 2.0.0-alpha.4 - 2020-07-26
### Changes
* Renamed AwsS3V3Filesystem to AwsS3V3Adapter (in line with other adapter names).
* Renamed the PHPSecLibV2 package to PhpseclibV2, Renamed the FTP package to Ftp.
* Public key and ss-agent authentication support for Sftp
### Fixes
* Allow creation of files with empty streams.
## 2.0.0-alpha.3 - 2020-03-21
### Fixes
* Corrected the required version for the sub-split packages.
## 2.0.0-alpha.2 - 2020-03-17
### Changes
* The `League\Flysystem\FilesystemAdapter::listContents` method returns an `iterable` instead of a `Generator`.
* The `League\Flysystem\DirectoryListing` class accepts an `iterable` instead of a `Generator`.
## 2.0.0-alpha.1 - 2020-03-09
* Initial 2.0.0 alpha release
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
conduct@flysystem.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: INFO.md
================================================
View the docs at: https://flysystem.thephpleague.com/docs/
Changelog at: https://github.com/thephpleague/flysystem/blob/3.x/CHANGELOG.md
================================================
FILE: LICENSE
================================================
Copyright (c) 2013-2026 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.
================================================
FILE: bin/.gitignore
================================================
renamespace.php
================================================
FILE: bin/check-versions.php
================================================
<?php
declare(strict_types=1);
/**
* This script check for composer dependency incompatibilities:.
*
* - All required dependencies of the extracted packages MUST be
* present in the main composer.json's require(-dev) section.
* - Dependency constraints of extracted packages may not exclude
* the constraints of the main package and vice versa.
* - The provided target release argument must be satisfiable by
* all the extracted packages' core dependency constraint.
*/
use Composer\Semver\Comparator;
use Composer\Semver\Semver;
use Composer\Semver\VersionParser;
use League\Flysystem\FileAttributes;
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
use League\Flysystem\StorageAttributes;
include_once __DIR__ . '/tools.php';
function constraint_has_conflict(string $mainConstraint, string $packageConstraint): bool
{
$parser = new VersionParser();
$mainConstraint = $parser->parseConstraints($mainConstraint);
$mainLowerBound = $mainConstraint->getLowerBound()->getVersion();
$mainUpperBound = $mainConstraint->getUpperBound()->getVersion();
$packageConstraint = $parser->parseConstraints($packageConstraint);
$packageLowerBound = $packageConstraint->getLowerBound()->getVersion();
$packageUpperBound = $packageConstraint->getUpperBound()->getVersion();
if (Comparator::compare($mainUpperBound, '<=', $packageLowerBound)) {
return true;
}
if (Comparator::compare($packageUpperBound, '<=', $mainLowerBound)) {
return true;
}
return false;
}
if ( ! isset($argv[1])) {
panic('No base version provided');
}
write_line("🔎 Inspecting composer dependency incompatibilities.");
$mainVersion = $argv[1];
$filesystem = new Filesystem(new LocalFilesystemAdapter(__DIR__ . '/../'));
$mainComposer = $filesystem->read('composer.json');
/** @var string[] $otherComposers */
$otherComposers = $filesystem->listContents('src', true)
->filter(function (StorageAttributes $item) {
return $item->isFile();
})
->filter(function (FileAttributes $item) {
return substr($item->path(), -5) === '.json';
})
->map(function (FileAttributes $item) {
return $item->path();
})
->toArray();
$mainInformation = json_decode($mainComposer, true);
foreach ($otherComposers as $composerFile) {
$information = json_decode($filesystem->read($composerFile), true);
foreach ($information['require'] as $dependency => $constraint) {
if (str_starts_with($dependency, 'ext-') || $dependency === 'phpseclib/phpseclib') {
continue;
}
if ($dependency === 'league/flysystem') {
if ( ! Semver::satisfies($mainVersion, $constraint)) {
panic("Composer file {$composerFile} does not allow league/flysystem:{$mainVersion}");
} else {
write_line("Composer file {$composerFile} allows league/flysystem:{$mainVersion} with {$constraint}");
}
continue;
}
$mainDependencyConstraint = $mainInformation['require'][$dependency]
?? $mainInformation['require-dev'][$dependency]
?? null;
if ( ! is_string($mainDependencyConstraint)) {
panic(
"The main composer file does not depend on an adapter dependency.\n" .
"Depedency {$dependency} from {$composerFile} is missing."
);
}
if (constraint_has_conflict($mainDependencyConstraint, $constraint)) {
panic(
"Package constraints are conflicting:\n\n" .
"Package composer file: {$composerFile}\n" .
"Dependency name: {$dependency}\n" .
"Main constraint: {$mainDependencyConstraint}\n" .
"Package constraint: {$constraint}"
);
}
}
}
write_line("✅ Composer dependencies are looking fine.");
================================================
FILE: bin/close-subsplit-prs.yml
================================================
---
name: Close sub-split PRs
on:
push:
branches:
- 2.x
- 3.x
pull_request:
branches:
- 2.x
- 3.x
schedule:
- cron: '30 7 * * *'
jobs:
close_subsplit_prs:
runs-on: ubuntu-latest
name: Close sub-split PRs
steps:
- uses: frankdejonge/action-close-subsplit-pr@0.1.0
with:
close_pr: 'yes'
target_branch_match: '^(?!master).+$'
message: |
Hi :wave:,
Thank you for contributing to Flysystem. Unfortunately, you've sent a PR to a read-only sub-split repository.
All pull requests should be directed towards: https://github.com/thephpleague/flysystem
================================================
FILE: bin/set-flysystem-version.php
================================================
<?php
use League\Flysystem\FileAttributes;
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
use League\Flysystem\StorageAttributes;
include_once __DIR__ . '/tools.php';
if ( ! isset($argv[1])) {
panic('No base version provided');
}
$mainVersion = $argv[1];
write_line("☝️ Setting all flysystem constraints to {$mainVersion}.");
$filesystem = new Filesystem(new LocalFilesystemAdapter(__DIR__ . '/../'));
/** @var string[] $otherComposers */
$composerFiles = $filesystem->listContents('src', true)
->filter(function (StorageAttributes $item) {
return $item->isFile();
})
->filter(function (FileAttributes $item) {
return substr($item->path(), -5) === '.json';
})
->map(function (FileAttributes $item) {
return $item->path();
})
->toArray();
foreach ($composerFiles as $composerFile) {
$contents = $filesystem->read($composerFile);
$mainVersionRegex = preg_quote($mainVersion, '~');
$updated = preg_replace('~("league/flysystem": "\\^[a-zA-Z0-9\\.-]+")~ms', '"league/flysystem": "^' . $mainVersion . '"', $contents);
$filesystem->write($composerFile, $updated);
}
================================================
FILE: bin/tools.php
================================================
<?php
include_once __DIR__ . '/../vendor/autoload.php';
function write_line(string $line)
{
fwrite(STDOUT, "{$line}\n");
}
function panic(string $reason)
{
write_line('🚨 ' . $reason);
exit(1);
}
================================================
FILE: bin/update-subsplit-closers.php
================================================
<?php
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
include __DIR__ . '/../vendor/autoload.php';
$filesystem = new Filesystem(new LocalFilesystemAdapter(realpath(__DIR__ . '/../')));
$subsplits = json_decode($filesystem->read('config.subsplit-publish.json'), true);
$workflowContents = $filesystem->read('bin/close-subsplit-prs.yml');
foreach ($subsplits['sub-splits'] as ['directory' => $subsplit]) {
$workflowPath = $subsplit . '/.github/workflows/close-subsplit-prs.yaml';
$filesystem->write($workflowPath, $workflowContents);
}
================================================
FILE: composer.json
================================================
{
"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/flysystem-local": "^3.0.0",
"league/mime-type-detection": "^1.0.0"
},
"require-dev": {
"ext-zip": "*",
"ext-fileinfo": "*",
"ext-ftp": "*",
"ext-mongodb": "^1.3|^2",
"microsoft/azure-storage-blob": "^1.1",
"phpunit/phpunit": "^9.5.11|^10.0",
"phpstan/phpstan": "^1.10",
"phpseclib/phpseclib": "^3.0.36",
"aws/aws-sdk-php": "^3.295.10",
"composer/semver": "^3.0",
"friendsofphp/php-cs-fixer": "^3.5",
"google/cloud-storage": "^1.23",
"async-aws/s3": "^1.5 || ^2.0",
"async-aws/simple-s3": "^1.1 || ^2.0",
"mongodb/mongodb": "^1.2|^2",
"sabre/dav": "^4.6.0",
"guzzlehttp/psr7": "^2.6"
},
"conflict": {
"async-aws/core": "<1.19.0",
"async-aws/s3": "<1.14.0",
"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"
}
],
"repositories": [
{
"type": "package",
"package": {
"name": "league/flysystem-local",
"version": "3.0.0",
"dist": {
"type": "path",
"url": "src/Local"
}
}
}
]
}
================================================
FILE: config.subsplit-publish.json
================================================
{
"sub-splits": [
{
"name": "ftp",
"directory": "src/Ftp",
"target": "git@github.com:thephpleague/flysystem-ftp.git"
},
{
"name": "sftp",
"directory": "src/PhpseclibV2",
"target": "git@github.com:thephpleague/flysystem-sftp.git"
},
{
"name": "sftp-v3",
"directory": "src/PhpseclibV3",
"target": "git@github.com:thephpleague/flysystem-sftp-v3.git"
},
{
"name": "memory",
"directory": "src/InMemory",
"target": "git@github.com:thephpleague/flysystem-memory.git"
},
{
"name": "local",
"directory": "src/Local",
"target": "git@github.com:thephpleague/flysystem-local.git"
},
{
"name": "ziparchive",
"directory": "src/ZipArchive",
"target": "git@github.com:thephpleague/flysystem-ziparchive.git"
},
{
"name": "aws-s3-v3",
"directory": "src/AwsS3V3",
"target": "git@github.com:thephpleague/flysystem-aws-s3-v3.git"
},
{
"name": "async-aws-s3",
"directory": "src/AsyncAwsS3",
"target": "git@github.com:thephpleague/flysystem-async-aws-s3.git"
},
{
"name": "azure-blob-storage",
"directory": "src/AzureBlobStorage",
"target": "git@github.com:thephpleague/flysystem-azure-blob-storage.git"
},
{
"name": "google-cloud-storage",
"directory": "src/GoogleCloudStorage",
"target": "git@github.com:thephpleague/flysystem-google-cloud-storage.git"
},
{
"name": "readonly",
"directory": "src/ReadOnly",
"target": "git@github.com:thephpleague/flysystem-read-only.git"
},
{
"name": "pathprefixing",
"directory": "src/PathPrefixing",
"target": "git@github.com:thephpleague/flysystem-path-prefixing.git"
},
{
"name": "webdav",
"directory": "src/WebDAV",
"target": "git@github.com:thephpleague/flysystem-webdav.git"
},
{
"name": "adapter-test-utilities",
"directory": "src/AdapterTestUtilities",
"target": "git@github.com:thephpleague/flysystem-adapter-test-utilities.git"
},
{
"name": "gridfs",
"directory": "src/GridFS",
"target": "git@github.com:thephpleague/flysystem-gridfs.git"
}
]
}
================================================
FILE: docker-compose.yml
================================================
---
version: "3"
services:
mongodb:
image: mongo:7
ports:
- "27017:27017"
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
================================================
FILE: mocked-functions.php
================================================
<?php
namespace League\Flysystem\Local {
function rmdir(...$arguments)
{
if ( ! is_mocked('rmdir')) {
return \rmdir(...$arguments);
}
return return_mocked_value('rmdir');
}
function unlink(...$arguments)
{
if ( ! is_mocked('unlink')) {
return \unlink(...$arguments);
}
return return_mocked_value('unlink');
}
function filemtime(...$arguments)
{
if ( ! is_mocked('filemtime')) {
return \filemtime(...$arguments);
}
return return_mocked_value('filemtime');
}
function filesize(...$arguments)
{
if ( ! is_mocked('filesize')) {
return \filesize(...$arguments);
}
return return_mocked_value('filesize');
}
}
namespace League\Flysystem\InMemory {
function time()
{
if ( ! is_mocked('time')) {
return \time();
}
return return_mocked_value('time');
}
}
namespace League\Flysystem\Ftp {
function ftp_raw(...$arguments)
{
if ( ! is_mocked('ftp_raw')) {
return \ftp_raw(...$arguments);
}
return return_mocked_value('ftp_raw');
}
function ftp_set_option(...$arguments)
{
if ( ! is_mocked('ftp_set_option')) {
return \ftp_set_option(...$arguments);
}
return return_mocked_value('ftp_set_option');
}
function ftp_pasv(...$arguments)
{
if ( ! is_mocked('ftp_pasv')) {
return \ftp_pasv(...$arguments);
}
return return_mocked_value('ftp_pasv');
}
function ftp_pwd(...$arguments)
{
if ( ! is_mocked('ftp_pwd')) {
return \ftp_pwd(...$arguments);
}
return return_mocked_value('ftp_pwd');
}
function ftp_fput(...$arguments)
{
if ( ! is_mocked('ftp_fput')) {
return \ftp_fput(...$arguments);
}
return return_mocked_value('ftp_fput');
}
function ftp_chmod(...$arguments)
{
if ( ! is_mocked('ftp_chmod')) {
return \ftp_chmod(...$arguments);
}
return return_mocked_value('ftp_chmod');
}
function ftp_mkdir(...$arguments)
{
if ( ! is_mocked('ftp_mkdir')) {
return \ftp_mkdir(...$arguments);
}
return return_mocked_value('ftp_mkdir');
}
function ftp_delete(...$arguments)
{
if ( ! is_mocked('ftp_delete')) {
return \ftp_delete(...$arguments);
}
return return_mocked_value('ftp_delete');
}
function ftp_rmdir(...$arguments)
{
if ( ! is_mocked('ftp_rmdir')) {
return \ftp_rmdir(...$arguments);
}
return return_mocked_value('ftp_rmdir');
}
function ftp_fget(...$arguments)
{
if ( ! is_mocked('ftp_fget')) {
return \ftp_fget(...$arguments);
}
return return_mocked_value('ftp_fget');
}
function ftp_rawlist(...$arguments)
{
if ( ! is_mocked('ftp_rawlist')) {
return \ftp_rawlist(...$arguments);
}
return return_mocked_value('ftp_rawlist');
}
}
namespace League\Flysystem\ZipArchive {
function stream_get_contents(...$arguments)
{
if ( ! is_mocked('stream_get_contents')) {
return \stream_get_contents(...$arguments);
}
return return_mocked_value('stream_get_contents');
}
}
================================================
FILE: phpstan-baseline.neon
================================================
parameters:
ignoreErrors:
-
message: "#^Parameter \\$connection of method League\\\\Flysystem\\\\Ftp\\\\FtpAdapter\\:\\:resolveConnectionRoot\\(\\) has invalid type FTP\\\\Connection\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Unsafe access to private property League\\\\Flysystem\\\\GoogleCloudStorage\\\\GoogleCloudStorageAdapter\\:\\:\\$algoToInfoMap through static\\:\\:\\.$#"
count: 1
path: src/GoogleCloudStorage/GoogleCloudStorageAdapter.php
-
message: "#^Unsafe access to private property League\\\\Flysystem\\\\GoogleCloudStorage\\\\GoogleCloudStorageAdapterTest\\:\\:\\$adapterPrefix through static\\:\\:\\.$#"
count: 3
path: src/GoogleCloudStorage/GoogleCloudStorageAdapterTest.php
-
message: "#^Unsafe access to private property League\\\\Flysystem\\\\GoogleCloudStorage\\\\GoogleCloudStorageAdapterTest\\:\\:\\$bucket through static\\:\\:\\.$#"
count: 5
path: src/GoogleCloudStorage/GoogleCloudStorageAdapterTest.php
-
message: "#^Unsafe access to private property League\\\\Flysystem\\\\GoogleCloudStorage\\\\GoogleCloudStorageAdapterTest\\:\\:\\$prefixer through static\\:\\:\\.$#"
count: 3
path: src/GoogleCloudStorage/GoogleCloudStorageAdapterTest.php
-
message: "#^Offset 2 does not exist on array\\{League\\\\Flysystem\\\\FilesystemOperator, string\\}\\.$#"
count: 1
path: src/MountManager.php
-
message: "#^Unsafe access to private property League\\\\Flysystem\\\\ZipArchive\\\\ZipArchiveAdapterTestCase\\:\\:\\$archiveProvider through static\\:\\:\\.$#"
count: 10
path: src/ZipArchive/ZipArchiveAdapterTestCase.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_chdir expects FTP\\\\Connection, resource given\\.$#"
count: 2
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_chmod expects FTP\\\\Connection, resource given\\.$#"
count: 2
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_delete expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_fget expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_fput expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_mdtm expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_mkdir expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_raw expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_rawlist expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_rename expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_rmdir expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpAdapter.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_size expects FTP\\\\Connection, resource given\\.$#"
count: 2
path: src/Ftp/FtpAdapter.php
-
message: "#^Method League\\\\Flysystem\\\\Ftp\\\\FtpConnectionProvider\\:\\:createConnectionResource\\(\\) should return resource but returns FTP\\\\Connection\\.$#"
count: 1
path: src/Ftp/FtpConnectionProvider.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_close expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpConnectionProvider.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_login expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpConnectionProvider.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_pasv expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpConnectionProvider.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_raw expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpConnectionProvider.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_set_option expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpConnectionProvider.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_close expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/FtpConnectionProviderTest.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_raw expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/NoopCommandConnectivityChecker.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_close expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/NoopCommandConnectivityCheckerTest.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_rawlist expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/RawListFtpConnectivityChecker.php
-
message: "#^Parameter \\#1 \\$ftp of function ftp_close expects FTP\\\\Connection, resource given\\.$#"
count: 1
path: src/Ftp/RawListFtpConnectivityCheckerTest.php
================================================
FILE: phpstan.neon
================================================
includes:
- phpstan-baseline.neon
parameters:
level: 6
paths:
- src
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: false
checkGenericClassInNonGenericObjectType: false
scanFiles:
- src/AdapterTestUtilities/test-functions.php
excludePaths:
- src/AdapterTestUtilities/
- src/AsyncAwsS3
- src/AwsS3V3
- src/FTP
- src/InMemory
- src/PhpseclibV2
- src/PhpseclibV3
ignoreErrors:
- '#invalid typehint type FTP\\Connection#'
- '#FTP\\Connection not found#'
- '#unknown class FTP\\Connection#'
- '#Call to function iterator_to_array\(\) on a separate line has no effect\.#'
- '#Comparison operation "<" between 0|1 and 4 is always true.#'
- '#Method League\\Flysystem\\AwsS3V3\\S3ClientStub.*#'
- '#Constant NET_SFTP_TYPE_DIRECTORY not found\.#'
- '#\$local_file of method phpseclib\\Net\\SFTP::get\(\) expects string, resource given#'
================================================
FILE: phpunit.php
================================================
<?php
include __DIR__ . '/vendor/autoload.php';
include __DIR__ . '/src/AdapterTestUtilities/test-functions.php';
include __DIR__ . '/mocked-functions.php';
================================================
FILE: phpunit.xml.dist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" bootstrap="phpunit.php">
<testsuites>
<testsuite name="Flysystem">
<directory suffix="Test.php">src/</directory>
</testsuite>
</testsuites>
<php>
<env name="FLYSYSTEM_TEST_SFTP" value="yes" />
</php>
<groups>
<exclude>
<group>legacy</group>
</exclude>
</groups>
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
</phpunit>
================================================
FILE: readme.md
================================================
# 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/)**
* **[MongoDB GridFS](https://flysystem.thephpleague.com/docs/adapter/gridfs/)**
* **[WebDAV](https://flysystem.thephpleague.com/docs/adapter/webdav/)**
* **[ZipArchive](https://flysystem.thephpleague.com/docs/adapter/zip-archive/)**
### Third party Adapters
* **[Azure Blob Storage](https://github.com/Azure-OSS/azure-storage-php-adapter-flysystem)**
* **[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)**
* **[ReplicateAdapter](https://github.com/ajgarlag/flysystem-replicate)**
* **[Uploadcare](https://github.com/vormkracht10/flysystem-uploadcare)**
* **[Useful adapters (FallbackAdapter, LogAdapter, ReadWriteAdapter, RetryAdapter)](https://github.com/ElGigi/FlysystemUsefulAdapters)**
* **[Metadata Cache](https://github.com/jgivoni/flysystem-cache-adapter)**
* **[Migration adapter (lazy)](https://github.com/antonsacred/flysystem-lazy-migration-adapter)**
You can always [create an adapter](https://flysystem.thephpleague.com/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).
================================================
FILE: src/AdapterTestUtilities/.gitattributes
================================================
* text=auto
.github export-ignore
.gitattributes export-ignore
README.md export-ignore
================================================
FILE: src/AdapterTestUtilities/.github/workflows/close-subsplit-prs.yaml
================================================
---
name: Close sub-split PRs
on:
push:
branches:
- 2.x
- 3.x
pull_request:
branches:
- 2.x
- 3.x
schedule:
- cron: '30 7 * * *'
jobs:
close_subsplit_prs:
runs-on: ubuntu-latest
name: Close sub-split PRs
steps:
- uses: frankdejonge/action-close-subsplit-pr@0.1.0
with:
close_pr: 'yes'
target_branch_match: '^(?!master).+$'
message: |
Hi :wave:,
Thank you for contributing to Flysystem. Unfortunately, you've sent a PR to a read-only sub-split repository.
All pull requests should be directed towards: https://github.com/thephpleague/flysystem
================================================
FILE: src/AdapterTestUtilities/ExceptionThrowingFilesystemAdapter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AdapterTestUtilities;
use League\Flysystem\Config;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\FilesystemOperationFailed;
class ExceptionThrowingFilesystemAdapter implements FilesystemAdapter
{
/**
* @var FilesystemAdapter
*/
private $adapter;
/**
* @var array<string, FilesystemOperationFailed>
*/
private $stagedExceptions = [];
public function __construct(FilesystemAdapter $adapter)
{
$this->adapter = $adapter;
}
public function stageException(string $method, string $path, FilesystemOperationFailed $exception): void
{
$this->stagedExceptions[join('@', [$method, $path])] = $exception;
}
private function throwStagedException(string $method, $path): void
{
$method = preg_replace('~.+::~', '', $method);
$key = join('@', [$method, $path]);
if ( ! array_key_exists($key, $this->stagedExceptions)) {
return;
}
$exception = $this->stagedExceptions[$key];
unset($this->stagedExceptions[$key]);
throw $exception;
}
public function fileExists(string $path): bool
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->fileExists($path);
}
public function write(string $path, string $contents, Config $config): void
{
$this->throwStagedException(__METHOD__, $path);
$this->adapter->write($path, $contents, $config);
}
public function writeStream(string $path, $contents, Config $config): void
{
$this->throwStagedException(__METHOD__, $path);
$this->adapter->writeStream($path, $contents, $config);
}
public function read(string $path): string
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->read($path);
}
public function readStream(string $path)
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->readStream($path);
}
public function delete(string $path): void
{
$this->throwStagedException(__METHOD__, $path);
$this->adapter->delete($path);
}
public function deleteDirectory(string $path): void
{
$this->throwStagedException(__METHOD__, $path);
$this->adapter->deleteDirectory($path);
}
public function createDirectory(string $path, Config $config): void
{
$this->throwStagedException(__METHOD__, $path);
$this->adapter->createDirectory($path, $config);
}
public function setVisibility(string $path, string $visibility): void
{
$this->throwStagedException(__METHOD__, $path);
$this->adapter->setVisibility($path, $visibility);
}
public function visibility(string $path): FileAttributes
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->visibility($path);
}
public function mimeType(string $path): FileAttributes
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->mimeType($path);
}
public function lastModified(string $path): FileAttributes
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->lastModified($path);
}
public function fileSize(string $path): FileAttributes
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->fileSize($path);
}
public function listContents(string $path, bool $deep): iterable
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->listContents($path, $deep);
}
public function move(string $source, string $destination, Config $config): void
{
$this->throwStagedException(__METHOD__, $source);
$this->adapter->move($source, $destination, $config);
}
public function copy(string $source, string $destination, Config $config): void
{
$this->throwStagedException(__METHOD__, $source);
$this->adapter->copy($source, $destination, $config);
}
public function directoryExists(string $path): bool
{
$this->throwStagedException(__METHOD__, $path);
return $this->adapter->directoryExists($path);
}
}
================================================
FILE: src/AdapterTestUtilities/FilesystemAdapterTestCase.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AdapterTestUtilities;
use const PHP_EOL;
use DateInterval;
use DateTimeImmutable;
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\StorageAttributes;
use League\Flysystem\UnableToCopyFile;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToProvideChecksum;
use League\Flysystem\UnableToReadFile;
use League\Flysystem\UnableToRetrieveMetadata;
use League\Flysystem\UnableToSetVisibility;
use League\Flysystem\UrlGeneration\PublicUrlGenerator;
use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
use League\Flysystem\Visibility;
use PHPUnit\Framework\TestCase;
use Throwable;
use function file_get_contents;
use function is_resource;
use function iterator_to_array;
/**
* @codeCoverageIgnore
*/
abstract class FilesystemAdapterTestCase extends TestCase
{
use RetryOnTestException;
/**
* @var FilesystemAdapter
*/
protected static $adapter;
/**
* @var bool
*/
protected $isUsingCustomAdapter = false;
public static function clearFilesystemAdapterCache(): void
{
static::$adapter = null;
}
abstract protected static function createFilesystemAdapter(): FilesystemAdapter;
public function adapter(): FilesystemAdapter
{
if ( ! static::$adapter instanceof FilesystemAdapter) {
static::$adapter = static::createFilesystemAdapter();
}
return static::$adapter;
}
public static function tearDownAfterClass(): void
{
self::clearFilesystemAdapterCache();
}
protected function setUp(): void
{
parent::setUp();
$this->adapter();
}
protected function useAdapter(FilesystemAdapter $adapter): FilesystemAdapter
{
static::$adapter = $adapter;
$this->isUsingCustomAdapter = true;
return $adapter;
}
/**
* @after
*/
public function cleanupAdapter(): void
{
$this->clearCustomAdapter();
$this->clearStorage();
}
public function clearStorage(): void
{
reset_function_mocks();
try {
$adapter = $this->adapter();
} catch (Throwable $exception) {
/*
* Setting up the filesystem adapter failed. This is OK at this stage.
* The exception will have been shown to the user when trying to run
* a test. We expect an exception to be thrown when tests are marked as
* skipped when a filesystem adapter cannot be constructed.
*/
return;
}
$this->runSetup(function () use ($adapter) {
/** @var StorageAttributes $item */
foreach ($adapter->listContents('', false) as $item) {
if ($item->isDir()) {
$adapter->deleteDirectory($item->path());
} else {
$adapter->delete($item->path());
}
}
});
}
public function clearCustomAdapter(): void
{
if ($this->isUsingCustomAdapter) {
$this->isUsingCustomAdapter = false;
self::clearFilesystemAdapterCache();
}
}
/**
* @test
*/
public function writing_and_reading_with_string(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('path.txt', 'contents', new Config());
$fileExists = $adapter->fileExists('path.txt');
$contents = $adapter->read('path.txt');
$this->assertTrue($fileExists);
$this->assertEquals('contents', $contents);
});
}
/**
* @test
*/
public function writing_a_file_with_a_stream(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$writeStream = stream_with_contents('contents');
$adapter->writeStream('path.txt', $writeStream, new Config([
Config::OPTION_VISIBILITY => Visibility::PUBLIC,
]));
if (is_resource($writeStream)) {
fclose($writeStream);
}
$fileExists = $adapter->fileExists('path.txt');
$this->assertTrue($fileExists);
});
}
/**
* @test
*
* @dataProvider filenameProvider
*/
public function writing_and_reading_files_with_special_path(string $path): void
{
$this->runScenario(function () use ($path) {
$adapter = $this->adapter();
$adapter->write($path, 'contents', new Config());
$contents = $adapter->read($path);
$this->assertEquals('contents', $contents);
});
}
public static function filenameProvider(): Generator
{
yield "a path with square brackets in filename 1" => ["some/file[name].txt"];
yield "a path with square brackets in filename 2" => ["some/file[0].txt"];
yield "a path with square brackets in filename 3" => ["some/file[10].txt"];
yield "a path with square brackets in dirname 1" => ["some[name]/file.txt"];
yield "a path with square brackets in dirname 2" => ["some[0]/file.txt"];
yield "a path with square brackets in dirname 3" => ["some[10]/file.txt"];
yield "a path with curly brackets in filename 1" => ["some/file{name}.txt"];
yield "a path with curly brackets in filename 2" => ["some/file{0}.txt"];
yield "a path with curly brackets in filename 3" => ["some/file{10}.txt"];
yield "a path with curly brackets in dirname 1" => ["some{name}/filename.txt"];
yield "a path with curly brackets in dirname 2" => ["some{0}/filename.txt"];
yield "a path with curly brackets in dirname 3" => ["some{10}/filename.txt"];
yield "a path with space in dirname" => ["some dir/filename.txt"];
yield "a path with space in filename" => ["somedir/file name.txt"];
}
/**
* @test
*/
public function writing_a_file_with_an_empty_stream(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$writeStream = stream_with_contents('');
$adapter->writeStream('path.txt', $writeStream, new Config());
if (is_resource($writeStream)) {
fclose($writeStream);
}
$fileExists = $adapter->fileExists('path.txt');
$this->assertTrue($fileExists);
$contents = $adapter->read('path.txt');
$this->assertEquals('', $contents);
});
}
/**
* @test
*/
public function listing_a_directory_named_0(): void
{
$this->givenWeHaveAnExistingFile('0/path.txt');
$this->givenWeHaveAnExistingFile('1/path.txt');
$this->runScenario(function () {
$listing = iterator_to_array($this->adapter()->listContents('0', false));
$this->assertCount(1, $listing);
});
}
/**
* @test
*/
public function reading_a_file(): void
{
$this->givenWeHaveAnExistingFile('path.txt', 'contents');
$this->runScenario(function () {
$contents = $this->adapter()->read('path.txt');
$this->assertEquals('contents', $contents);
});
}
/**
* @test
*/
public function reading_a_file_with_a_stream(): void
{
$this->givenWeHaveAnExistingFile('path.txt', 'contents');
$this->runScenario(function () {
$readStream = $this->adapter()->readStream('path.txt');
$contents = stream_get_contents($readStream);
$this->assertIsResource($readStream);
$this->assertEquals('contents', $contents);
fclose($readStream);
});
}
/**
* @test
*/
public function overwriting_a_file(): void
{
$this->runScenario(function () {
$this->givenWeHaveAnExistingFile('path.txt', 'contents', ['visibility' => Visibility::PUBLIC]);
$adapter = $this->adapter();
$adapter->write('path.txt', 'new contents', new Config(['visibility' => Visibility::PRIVATE]));
$contents = $adapter->read('path.txt');
$this->assertEquals('new contents', $contents);
$visibility = $adapter->visibility('path.txt')->visibility();
$this->assertEquals(Visibility::PRIVATE, $visibility);
});
}
/**
* @test
*/
public function a_file_exists_only_when_it_is_written_and_not_deleted(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
// does not exist before creation
self::assertFalse($adapter->fileExists('path.txt'));
// a file exists after creation
$this->givenWeHaveAnExistingFile('path.txt');
self::assertTrue($adapter->fileExists('path.txt'));
// a file no longer exists after creation
$adapter->delete('path.txt');
self::assertFalse($adapter->fileExists('path.txt'));
});
}
/**
* @test
*/
public function listing_contents_shallow(): void
{
$this->runScenario(function () {
$this->givenWeHaveAnExistingFile('some/0-path.txt', 'contents');
$this->givenWeHaveAnExistingFile('some/1-nested/path.txt', 'contents');
$listing = $this->adapter()->listContents('some', false);
/** @var StorageAttributes[] $items */
$items = iterator_to_array($listing);
$this->assertInstanceOf(Generator::class, $listing);
$this->assertContainsOnlyInstancesOf(StorageAttributes::class, $items);
$this->assertCount(2, $items, $this->formatIncorrectListingCount($items));
// Order of entries is not guaranteed
[$fileIndex, $directoryIndex] = $items[0]->isFile() ? [0, 1] : [1, 0];
$this->assertEquals('some/0-path.txt', $items[$fileIndex]->path());
$this->assertEquals('some/1-nested', $items[$directoryIndex]->path());
$this->assertTrue($items[$fileIndex]->isFile());
$this->assertTrue($items[$directoryIndex]->isDir());
});
}
/**
* @test
*/
public function checking_if_a_non_existing_directory_exists(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
self::assertFalse($adapter->directoryExists('this-does-not-exist.php'));
});
}
/**
* @test
*/
public function checking_if_a_directory_exists_after_writing_a_file(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$this->givenWeHaveAnExistingFile('existing-directory/file.txt');
self::assertTrue($adapter->directoryExists('existing-directory'));
});
}
/**
* @test
*/
public function checking_if_a_directory_exists_after_creating_it(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->createDirectory('explicitly-created-directory', new Config());
self::assertTrue($adapter->directoryExists('explicitly-created-directory'));
$adapter->deleteDirectory('explicitly-created-directory');
$l = iterator_to_array($adapter->listContents('/', false), false);
self::assertEquals([], $l);
self::assertFalse($adapter->directoryExists('explicitly-created-directory'));
});
}
/**
* @test
*/
public function listing_contents_recursive(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->createDirectory('path', new Config());
$adapter->write('path/file.txt', 'string', new Config());
$listing = $adapter->listContents('', true);
/** @var StorageAttributes[] $items */
$items = iterator_to_array($listing);
$this->assertCount(2, $items, $this->formatIncorrectListingCount($items));
});
}
protected function formatIncorrectListingCount(array $items): string
{
$message = "Incorrect number of items returned.\nThe listing contains:\n\n";
/** @var StorageAttributes $item */
foreach ($items as $item) {
$message .= "- {$item->path()}\n";
}
return $message . PHP_EOL;
}
protected function givenWeHaveAnExistingFile(string $path, string $contents = 'contents', array $config = []): void
{
$this->runSetup(function () use ($path, $contents, $config) {
$this->adapter()->write($path, $contents, new Config($config));
});
}
/**
* @test
*/
public function fetching_file_size(): void
{
$adapter = $this->adapter();
$this->givenWeHaveAnExistingFile('path.txt', 'contents');
$this->runScenario(function () use ($adapter) {
$attributes = $adapter->fileSize('path.txt');
$this->assertInstanceOf(FileAttributes::class, $attributes);
$this->assertEquals(8, $attributes->fileSize());
});
}
/**
* @test
*/
public function setting_visibility(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$this->givenWeHaveAnExistingFile('path.txt', 'contents', [Config::OPTION_VISIBILITY => Visibility::PUBLIC]);
$this->assertEquals(Visibility::PUBLIC, $adapter->visibility('path.txt')->visibility());
$adapter->setVisibility('path.txt', Visibility::PRIVATE);
$this->assertEquals(Visibility::PRIVATE, $adapter->visibility('path.txt')->visibility());
$adapter->setVisibility('path.txt', Visibility::PUBLIC);
$this->assertEquals(Visibility::PUBLIC, $adapter->visibility('path.txt')->visibility());
});
}
/**
* @test
*/
public function fetching_file_size_of_a_directory(): void
{
$this->expectException(UnableToRetrieveMetadata::class);
$adapter = $this->adapter();
$this->runScenario(function () use ($adapter) {
$adapter->createDirectory('path', new Config());
$adapter->fileSize('path/');
});
}
/**
* @test
*/
public function fetching_file_size_of_non_existing_file(): void
{
$this->expectException(UnableToRetrieveMetadata::class);
$this->runScenario(function () {
$this->adapter()->fileSize('non-existing-file.txt');
});
}
/**
* @test
*/
public function fetching_last_modified_of_non_existing_file(): void
{
$this->expectException(UnableToRetrieveMetadata::class);
$this->runScenario(function () {
$this->adapter()->lastModified('non-existing-file.txt');
});
}
/**
* @test
*/
public function fetching_visibility_of_non_existing_file(): void
{
$this->expectException(UnableToRetrieveMetadata::class);
$this->runScenario(function () {
$this->adapter()->visibility('non-existing-file.txt');
});
}
/**
* @test
*/
public function fetching_the_mime_type_of_an_svg_file(): void
{
$this->runScenario(function () {
$this->givenWeHaveAnExistingFile('file.svg', file_get_contents(__DIR__ . '/test_files/flysystem.svg'));
$mimetype = $this->adapter()->mimeType('file.svg')->mimeType();
$this->assertStringStartsWith('image/svg+xml', $mimetype);
});
}
/**
* @test
*/
public function fetching_mime_type_of_non_existing_file(): void
{
$this->expectException(UnableToRetrieveMetadata::class);
$this->runScenario(function () {
$this->adapter()->mimeType('non-existing-file.txt');
});
}
/**
* @test
*/
public function fetching_unknown_mime_type_of_a_file(): void
{
$this->givenWeHaveAnExistingFile(
'unknown-mime-type.md5',
file_get_contents(__DIR__ . '/test_files/unknown-mime-type.md5')
);
$this->expectException(UnableToRetrieveMetadata::class);
$this->runScenario(function () {
$this->adapter()->mimeType('unknown-mime-type.md5');
});
}
/**
* @test
*/
public function listing_a_toplevel_directory(): void
{
$this->givenWeHaveAnExistingFile('path1.txt');
$this->givenWeHaveAnExistingFile('path2.txt');
$this->runScenario(function () {
$contents = iterator_to_array($this->adapter()->listContents('', true));
$this->assertCount(2, $contents);
});
}
/**
* @test
*/
public function writing_and_reading_with_streams(): void
{
$this->runScenario(function () {
$writeStream = stream_with_contents('contents');
$adapter = $this->adapter();
$adapter->writeStream('path.txt', $writeStream, new Config());
if (is_resource($writeStream)) {
fclose($writeStream);
};
$readStream = $adapter->readStream('path.txt');
$this->assertIsResource($readStream);
$contents = stream_get_contents($readStream);
fclose($readStream);
$this->assertEquals('contents', $contents);
});
}
/**
* @test
*/
public function setting_visibility_on_a_file_that_does_not_exist(): void
{
$this->expectException(UnableToSetVisibility::class);
$this->runScenario(function () {
$this->adapter()->setVisibility('this-path-does-not-exists.txt', Visibility::PRIVATE);
});
}
/**
* @test
*/
public function copying_a_file(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->copy('source.txt', 'destination.txt', new Config());
$this->assertTrue($adapter->fileExists('source.txt'));
$this->assertTrue($adapter->fileExists('destination.txt'));
$this->assertEquals(Visibility::PUBLIC, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('text/plain', $adapter->mimeType('destination.txt')->mimeType());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
/**
* @test
*/
public function copying_a_file_that_does_not_exist(): void
{
$this->expectException(UnableToCopyFile::class);
$this->runScenario(function () {
$this->adapter()->copy('source.txt', 'destination.txt', new Config());
});
}
/**
* @test
*/
public function copying_a_file_again(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->copy('source.txt', 'destination.txt', new Config());
$this->assertTrue($adapter->fileExists('source.txt'));
$this->assertTrue($adapter->fileExists('destination.txt'));
$this->assertEquals(Visibility::PUBLIC, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
/**
* @test
*/
public function moving_a_file(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->move('source.txt', 'destination.txt', new Config());
$this->assertFalse(
$adapter->fileExists('source.txt'),
'After moving a file should no longer exist in the original location.'
);
$this->assertTrue(
$adapter->fileExists('destination.txt'),
'After moving, a file should be present at the new location.'
);
$this->assertEquals(Visibility::PUBLIC, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('text/plain', $adapter->mimeType('destination.txt')->mimeType());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
/**
* @test
*/
public function file_exists_on_directory_is_false(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$this->assertFalse($adapter->directoryExists('test'));
$adapter->createDirectory('test', new Config());
$this->assertTrue($adapter->directoryExists('test'));
$this->assertFalse($adapter->fileExists('test'));
});
}
/**
* @test
*/
public function directory_exists_on_file_is_false(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$this->assertFalse($adapter->fileExists('test.txt'));
$adapter->write('test.txt', 'content', new Config());
$this->assertTrue($adapter->fileExists('test.txt'));
$this->assertFalse($adapter->directoryExists('test.txt'));
});
}
/**
* @test
*/
public function reading_a_file_that_does_not_exist(): void
{
$this->expectException(UnableToReadFile::class);
$this->runScenario(function () {
$this->adapter()->read('path.txt');
});
}
/**
* @test
*/
public function moving_a_file_that_does_not_exist(): void
{
$this->expectException(UnableToMoveFile::class);
$this->runScenario(function () {
$this->adapter()->move('source.txt', 'destination.txt', new Config());
});
}
/**
* @test
*/
public function trying_to_delete_a_non_existing_file(): void
{
$adapter = $this->adapter();
$adapter->delete('path.txt');
$fileExists = $adapter->fileExists('path.txt');
$this->assertFalse($fileExists);
}
/**
* @test
*/
public function checking_if_files_exist(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$fileExistsBefore = $adapter->fileExists('some/path.txt');
$adapter->write('some/path.txt', 'contents', new Config());
$fileExistsAfter = $adapter->fileExists('some/path.txt');
$this->assertFalse($fileExistsBefore);
$this->assertTrue($fileExistsAfter);
});
}
/**
* @test
*/
public function fetching_last_modified(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('path.txt', 'contents', new Config());
$attributes = $adapter->lastModified('path.txt');
$this->assertInstanceOf(FileAttributes::class, $attributes);
$this->assertIsInt($attributes->lastModified());
$this->assertTrue($attributes->lastModified() > time() - 30);
$this->assertTrue($attributes->lastModified() < time() + 30);
});
}
/**
* @test
*/
public function failing_to_read_a_non_existing_file_into_a_stream(): void
{
$this->expectException(UnableToReadFile::class);
$this->adapter()->readStream('something.txt');
}
/**
* @test
*/
public function failing_to_read_a_non_existing_file(): void
{
$this->expectException(UnableToReadFile::class);
$this->adapter()->read('something.txt');
}
/**
* @test
*/
public function creating_a_directory(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->createDirectory('creating_a_directory/path', new Config());
// Creating a directory should be idempotent.
$adapter->createDirectory('creating_a_directory/path', new Config());
$contents = iterator_to_array($adapter->listContents('creating_a_directory', false));
$this->assertCount(1, $contents, $this->formatIncorrectListingCount($contents));
/** @var DirectoryAttributes $directory */
$directory = $contents[0];
$this->assertInstanceOf(DirectoryAttributes::class, $directory);
$this->assertEquals('creating_a_directory/path', $directory->path());
$adapter->deleteDirectory('creating_a_directory/path');
});
}
/**
* @test
*/
public function copying_a_file_with_collision(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('path.txt', 'new contents', new Config());
$adapter->write('new-path.txt', 'contents', new Config());
$adapter->copy('path.txt', 'new-path.txt', new Config());
$contents = $adapter->read('new-path.txt');
$this->assertEquals('new contents', $contents);
});
}
/**
* @test
*/
public function moving_a_file_with_collision(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('path.txt', 'new contents', new Config());
$adapter->write('new-path.txt', 'contents', new Config());
$adapter->move('path.txt', 'new-path.txt', new Config());
$oldFileExists = $adapter->fileExists('path.txt');
$this->assertFalse($oldFileExists);
$contents = $adapter->read('new-path.txt');
$this->assertEquals('new contents', $contents);
});
}
/**
* @test
*/
public function copying_a_file_with_same_destination(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('path.txt', 'new contents', new Config());
$adapter->copy('path.txt', 'path.txt', new Config());
$contents = $adapter->read('path.txt');
$this->assertEquals('new contents', $contents);
});
}
/**
* @test
*/
public function moving_a_file_with_same_destination(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('path.txt', 'new contents', new Config());
$adapter->move('path.txt', 'path.txt', new Config());
$contents = $adapter->read('path.txt');
$this->assertEquals('new contents', $contents);
});
}
protected function assertFileExistsAtPath(string $path): void
{
$this->runScenario(function () use ($path) {
$fileExists = $this->adapter()->fileExists($path);
$this->assertTrue($fileExists);
});
}
/**
* @test
*/
public function generating_a_public_url(): void
{
$adapter = $this->adapter();
if ( ! $adapter instanceof PublicUrlGenerator) {
$this->markTestSkipped('Adapter does not supply public URls');
}
$adapter->write('some/path.txt', 'public contents', new Config(['visibility' => 'public']));
$url = $adapter->publicUrl('some/path.txt', new Config());
$contents = file_get_contents($url);
self::assertEquals('public contents', $contents);
}
/**
* @test
*/
public function generating_a_temporary_url(): void
{
$adapter = $this->adapter();
if ( ! $adapter instanceof TemporaryUrlGenerator) {
$this->markTestSkipped('Adapter does not supply temporary URls');
}
$adapter->write('some/private.txt', 'public contents', new Config(['visibility' => 'private']));
$expiresAt = (new DateTimeImmutable())->add(DateInterval::createFromDateString('1 minute'));
$url = $adapter->temporaryUrl('some/private.txt', $expiresAt, new Config());
$contents = file_get_contents($url);
self::assertEquals('public contents', $contents);
}
/**
* @test
*/
public function get_checksum(): void
{
$adapter = $this->adapter();
if ( ! $adapter instanceof ChecksumProvider) {
$this->markTestSkipped('Adapter does not supply providing checksums');
}
$adapter->write('path.txt', 'foobar', new Config());
$this->assertSame('3858f62230ac3c915f300c664312c63f', $adapter->checksum('path.txt', new Config()));
}
/**
* @test
*/
public function cannot_get_checksum_for_non_existent_file(): void
{
$adapter = $this->adapter();
if ( ! $adapter instanceof ChecksumProvider) {
$this->markTestSkipped('Adapter does not supply providing checksums');
}
$this->expectException(UnableToProvideChecksum::class);
$adapter->checksum('path.txt', new Config());
}
/**
* @test
*/
public function cannot_get_checksum_for_directory(): void
{
$adapter = $this->adapter();
if ( ! $adapter instanceof ChecksumProvider) {
$this->markTestSkipped('Adapter does not supply providing checksums');
}
$adapter->createDirectory('dir', new Config());
$this->expectException(UnableToProvideChecksum::class);
$adapter->checksum('dir', new Config());
}
}
================================================
FILE: src/AdapterTestUtilities/README.md
================================================
## Flysystem Adapter Test Utilities
> ⚠️ this is a sub-split, for pull requests and issues, visit: https://github.com/thephpleague/flysystem
Require this package to make use of some adapter test utilities.
```bash
composer require --dev league/flysystem-adapter-test-utilities
```
View the [documentation of Flysystem](https://flysystem.thephpleague.com/docs/).
================================================
FILE: src/AdapterTestUtilities/RetryOnTestException.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AdapterTestUtilities;
use const PHP_EOL;
use const STDOUT;
use League\Flysystem\FilesystemException;
use Throwable;
/**
* @codeCoverageIgnore
*/
trait RetryOnTestException
{
/**
* @var string
*/
protected $exceptionTypeToRetryOn;
/**
* @var int
*/
protected $timeoutForExceptionRetry = 2;
protected function retryOnException(string $className, int $timout = 2): void
{
$this->exceptionTypeToRetryOn = $className;
$this->timeoutForExceptionRetry = $timout;
}
protected function retryScenarioOnException(string $className, callable $scenario, int $timeout = 2): void
{
$this->retryOnException($className, $timeout);
$this->runScenario($scenario);
}
protected function dontRetryOnException(): void
{
$this->exceptionTypeToRetryOn = null;
}
/**
* @internal
*
* @throws Throwable
*/
protected function runSetup(callable $scenario): void
{
$previousException = $this->exceptionTypeToRetryOn;
$previousTimeout = $this->timeoutForExceptionRetry;
$this->retryOnException(FilesystemException::class);
try {
$this->runScenario($scenario);
} finally {
$this->exceptionTypeToRetryOn = $previousException;
$this->timeoutForExceptionRetry = $previousTimeout;
}
}
protected function runScenario(callable $scenario): void
{
if ($this->exceptionTypeToRetryOn === null) {
$scenario();
return;
}
$firstTryAt = \time();
$lastTryAt = $firstTryAt + 60;
while (time() <= $lastTryAt) {
try {
$scenario();
return;
} catch (Throwable $exception) {
if ( ! $exception instanceof $this->exceptionTypeToRetryOn) {
throw $exception;
}
fwrite(STDOUT, 'Retrying ...' . PHP_EOL);
sleep($this->timeoutForExceptionRetry);
}
}
$this->exceptionTypeToRetryOn = null;
if (isset($exception) && $exception instanceof Throwable) {
throw $exception;
}
}
}
================================================
FILE: src/AdapterTestUtilities/ToxiproxyManagement.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AdapterTestUtilities;
use GuzzleHttp\Client;
/**
* This class provides a client for the HTTP API provided by the proxy that simulates network issues.
*
* @see https://github.com/shopify/toxiproxy#http-api
*
* @phpstan-type RegisteredProxies 'ftp'|'sftp'|'ftpd'
* @phpstan-type StreamDirection 'upstream'|'downstream'
* @phpstan-type Type 'latency'|'bandwidth'|'slow_close'|'timeout'|'reset_peer'|'slicer'|'limit_data'
* @phpstan-type Attributes array{latency?: int, jitter?: int, rate?: int, delay?: int}
* @phpstan-type Toxic array{name?: string, type: Type, stream?: StreamDirection, toxicity?: float, attributes: Attributes}
*/
final class ToxiproxyManagement
{
/** @var Client */
private $apiClient;
public function __construct(Client $apiClient)
{
$this->apiClient = $apiClient;
}
public static function forServer(string $apiUri = 'http://localhost:8474'): self
{
return new self(
new Client(
[
'base_uri' => $apiUri,
'base_url' => $apiUri, // Compatibility with older versions of Guzzle
]
)
);
}
public function removeAllToxics(): void
{
$this->apiClient->post('/reset');
}
/**
* Simulates a peer reset on the client->server direction.
*
* @param RegisteredProxies $proxyName
*/
public function resetPeerOnRequest(
string $proxyName,
int $timeoutInMilliseconds
): void {
$configuration = [
'type' => 'reset_peer',
'stream' => 'upstream',
'attributes' => ['timeout' => $timeoutInMilliseconds],
];
$this->addToxic($proxyName, $configuration);
}
/**
* Registers a network toxic for the given proxy.
*
* @param RegisteredProxies $proxyName
* @param Toxic $configuration
*/
private function addToxic(string $proxyName, array $configuration): void
{
$this->apiClient->post('/proxies/' . $proxyName . '/toxics', ['json' => $configuration]);
}
}
================================================
FILE: src/AdapterTestUtilities/composer.json
================================================
{
"name": "league/flysystem-adapter-test-utilities",
"description": "Flysystem utilities for testing adapters.",
"keywords": ["filesystem", "flysystem", "adapter", "test", "utilities"],
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"League\\Flysystem\\AdapterTestUtilities\\": ""
},
"files": [
"test-functions.php"
]
},
"require": {
"php": "^8.0.2",
"league/flysystem": "^3.0.0"
},
"license": "MIT",
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
}
]
}
================================================
FILE: src/AdapterTestUtilities/test-functions.php
================================================
<?php
declare(strict_types=1);
function return_mocked_value(string $name)
{
return array_shift($_ENV['__FM:RETURNS:' . $name]);
}
function reset_function_mocks()
{
foreach (array_keys($_ENV) as $name) {
if (is_string($name) && substr($name, 0, 5) === '__FM:') {
unset($_ENV[$name]);
}
}
}
function mock_function(string $name, ...$returns)
{
$_ENV['__FM:FUNC_IS_MOCKED:' . $name] = 'yes';
$_ENV['__FM:RETURNS:' . $name] = $returns;
}
function is_mocked(string $name)
{
return ($_ENV['__FM:FUNC_IS_MOCKED:' . $name] ?? 'no') === 'yes';
}
function stream_with_contents(string $contents)
{
$stream = fopen('php://temp', 'w+b');
fwrite($stream, $contents);
rewind($stream);
return $stream;
}
function delete_directory(string $dir): void
{
if ( ! is_dir($dir)) {
return;
}
foreach ((array) scandir($dir) as $file) {
if ('.' === $file || '..' === $file) {
continue;
}
if (is_dir("$dir/$file")) {
delete_directory("$dir/$file");
} else {
unlink("$dir/$file");
}
}
rmdir($dir);
}
================================================
FILE: src/AdapterTestUtilities/test_files/unknown-mime-type.md5
================================================
141d15ed35fc57dcc3c72bba881742b1
================================================
FILE: src/AsyncAwsS3/.gitattributes
================================================
* text=auto
.github export-ignore
.gitattributes export-ignore
.gitignore export-ignore
**/*Test.php export-ignore
**/*Stub.php export-ignore
README.md export-ignore
================================================
FILE: src/AsyncAwsS3/.github/workflows/close-subsplit-prs.yaml
================================================
---
name: Close sub-split PRs
on:
push:
branches:
- 2.x
- 3.x
pull_request:
branches:
- 2.x
- 3.x
schedule:
- cron: '30 7 * * *'
jobs:
close_subsplit_prs:
runs-on: ubuntu-latest
name: Close sub-split PRs
steps:
- uses: frankdejonge/action-close-subsplit-pr@0.1.0
with:
close_pr: 'yes'
target_branch_match: '^(?!master).+$'
message: |
Hi :wave:,
Thank you for contributing to Flysystem. Unfortunately, you've sent a PR to a read-only sub-split repository.
All pull requests should be directed towards: https://github.com/thephpleague/flysystem
================================================
FILE: src/AsyncAwsS3/AsyncAwsS3Adapter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AsyncAwsS3;
use AsyncAws\Core\Exception\Http\ClientException;
use AsyncAws\Core\Stream\ResultStream;
use AsyncAws\S3\Input\GetObjectRequest;
use AsyncAws\S3\Result\HeadObjectOutput;
use AsyncAws\S3\S3Client;
use AsyncAws\S3\ValueObject\AwsObject;
use AsyncAws\S3\ValueObject\CommonPrefix;
use AsyncAws\S3\ValueObject\ObjectIdentifier;
use AsyncAws\SimpleS3\SimpleS3Client;
use DateTimeImmutable;
use DateTimeInterface;
use Generator;
use League\Flysystem\ChecksumAlgoIsNotSupported;
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\StorageAttributes;
use League\Flysystem\UnableToCheckDirectoryExistence;
use League\Flysystem\UnableToCheckFileExistence;
use League\Flysystem\UnableToCopyFile;
use League\Flysystem\UnableToCreateDirectory;
use League\Flysystem\UnableToDeleteDirectory;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToGeneratePublicUrl;
use League\Flysystem\UnableToGenerateTemporaryUrl;
use League\Flysystem\UnableToListContents;
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\UrlGeneration\PublicUrlGenerator;
use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
use League\Flysystem\Visibility;
use League\MimeTypeDetection\FinfoMimeTypeDetector;
use League\MimeTypeDetection\MimeTypeDetector;
use Throwable;
use function trim;
class AsyncAwsS3Adapter implements FilesystemAdapter, PublicUrlGenerator, ChecksumProvider, TemporaryUrlGenerator
{
/**
* @var string[]
*/
public const AVAILABLE_OPTIONS = [
'ACL',
'CacheControl',
'ContentDisposition',
'ContentEncoding',
'ContentLength',
'ContentType',
'ContentMD5',
'Expires',
'GrantFullControl',
'GrantRead',
'GrantReadACP',
'GrantWriteACP',
'Metadata',
'MetadataDirective',
'RequestPayer',
'SSECustomerAlgorithm',
'SSECustomerKey',
'SSECustomerKeyMD5',
'SSEKMSKeyId',
'ServerSideEncryption',
'StorageClass',
'Tagging',
'WebsiteRedirectLocation',
'ChecksumAlgorithm',
'CopySourceSSECustomerAlgorithm',
'CopySourceSSECustomerKey',
'CopySourceSSECustomerKeyMD5',
];
/**
* @var string[]
*/
protected const EXTRA_METADATA_FIELDS = [
'Metadata',
'StorageClass',
'ETag',
'VersionId',
];
private PathPrefixer $prefixer;
private VisibilityConverter $visibility;
private MimeTypeDetector $mimeTypeDetector;
/**
* @var array|string[]
*/
private array $forwardedOptions;
/**
* @var array|string[]
*/
private array $metadataFields;
/**
* @param S3Client|SimpleS3Client $client Uploading of files larger than 5GB is only supported with SimpleS3Client
*/
public function __construct(
private S3Client $client,
private string $bucket,
string $prefix = '',
?VisibilityConverter $visibility = null,
?MimeTypeDetector $mimeTypeDetector = null,
array $forwardedOptions = self::AVAILABLE_OPTIONS,
array $metadataFields = self::EXTRA_METADATA_FIELDS,
) {
$this->prefixer = new PathPrefixer($prefix);
$this->visibility = $visibility ?? new PortableVisibilityConverter();
$this->mimeTypeDetector = $mimeTypeDetector ?? new FinfoMimeTypeDetector();
$this->forwardedOptions = $forwardedOptions;
$this->metadataFields = $metadataFields;
}
public function fileExists(string $path): bool
{
try {
return $this->client->objectExists(
[
'Bucket' => $this->bucket,
'Key' => $this->prefixer->prefixPath($path),
]
)->isSuccess();
} catch (ClientException $e) {
throw UnableToCheckFileExistence::forLocation($path, $e);
}
}
public function write(string $path, string $contents, Config $config): void
{
$this->upload($path, $contents, $config);
}
public function writeStream(string $path, $contents, Config $config): void
{
$this->upload($path, $contents, $config);
}
public function read(string $path): string
{
$body = $this->readObject($path);
return $body->getContentAsString();
}
public function readStream(string $path)
{
$body = $this->readObject($path);
return $body->getContentAsResource();
}
public function delete(string $path): void
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
try {
$this->client->deleteObject($arguments);
} catch (Throwable $exception) {
throw UnableToDeleteFile::atLocation($path, '', $exception);
}
}
public function deleteDirectory(string $path): void
{
$prefix = $this->prefixer->prefixDirectoryPath($path);
$prefix = ltrim($prefix, '/');
$objects = [];
$params = ['Bucket' => $this->bucket, 'Prefix' => $prefix];
try {
$result = $this->client->listObjectsV2($params);
/** @var AwsObject $item */
foreach ($result->getContents() as $item) {
$key = $item->getKey();
if (null !== $key) {
$objects[] = $this->createObjectIdentifierForXmlRequest($key);
}
}
if (empty($objects)) {
return;
}
foreach (array_chunk($objects, 1000) as $chunk) {
$this->client->deleteObjects([
'Bucket' => $this->bucket,
'Delete' => ['Objects' => $chunk],
]);
}
} catch (\Throwable $e) {
throw UnableToDeleteDirectory::atLocation($path, $e->getMessage(), $e);
}
}
public function createDirectory(string $path, Config $config): void
{
$defaultVisibility = $config->get(Config::OPTION_DIRECTORY_VISIBILITY, $this->visibility->defaultForDirectories());
$config = $config->withDefaults([Config::OPTION_VISIBILITY => $defaultVisibility]);
try {
$this->upload(rtrim($path, '/') . '/', '', $config);
} catch (Throwable $e) {
throw UnableToCreateDirectory::dueToFailure($path, $e);
}
}
public function setVisibility(string $path, string $visibility): void
{
$arguments = [
'Bucket' => $this->bucket,
'Key' => $this->prefixer->prefixPath($path),
'ACL' => $this->visibility->visibilityToAcl($visibility),
];
try {
$this->client->putObjectAcl($arguments);
} catch (Throwable $exception) {
throw UnableToSetVisibility::atLocation($path, $exception->getMessage(), $exception);
}
}
public function visibility(string $path): FileAttributes
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
try {
$result = $this->client->getObjectAcl($arguments);
$grants = $result->getGrants();
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::visibility($path, $exception->getMessage(), $exception);
}
$visibility = $this->visibility->aclToVisibility($grants);
return new FileAttributes($path, null, $visibility);
}
public function mimeType(string $path): FileAttributes
{
$attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_MIME_TYPE);
if (null === $attributes->mimeType()) {
throw UnableToRetrieveMetadata::mimeType($path);
}
return $attributes;
}
public function lastModified(string $path): FileAttributes
{
$attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_LAST_MODIFIED);
if (null === $attributes->lastModified()) {
throw UnableToRetrieveMetadata::lastModified($path);
}
return $attributes;
}
public function fileSize(string $path): FileAttributes
{
$attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_FILE_SIZE);
if (null === $attributes->fileSize()) {
throw UnableToRetrieveMetadata::fileSize($path);
}
return $attributes;
}
public function directoryExists(string $path): bool
{
try {
$prefix = $this->prefixer->prefixDirectoryPath($path);
$options = ['Bucket' => $this->bucket, 'Prefix' => $prefix, 'MaxKeys' => 1, 'Delimiter' => '/'];
return $this->client->listObjectsV2($options)->getKeyCount() > 0;
} catch (Throwable $exception) {
throw UnableToCheckDirectoryExistence::forLocation($path, $exception);
}
}
public function listContents(string $path, bool $deep): iterable
{
$path = trim($path, '/');
$prefix = trim($this->prefixer->prefixPath($path), '/');
$prefix = $prefix === '' ? '' : $prefix . '/';
$options = ['Bucket' => $this->bucket, 'Prefix' => $prefix];
if (false === $deep) {
$options['Delimiter'] = '/';
}
try {
$listing = $this->retrievePaginatedListing($options);
foreach ($listing as $item) {
$item = $this->mapS3ObjectMetadata($item);
if ($item->path() === $path) {
continue;
}
yield $item;
}
} catch (\Throwable $e) {
throw UnableToListContents::atLocation($path, $deep, $e);
}
}
public function move(string $source, string $destination, Config $config): void
{
if ($source === $destination) {
return;
}
try {
$this->copy($source, $destination, $config);
$this->delete($source);
} catch (Throwable $exception) {
throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
}
}
public function copy(string $source, string $destination, Config $config): void
{
if ($source === $destination) {
return;
}
try {
$visibility = $config->get(Config::OPTION_VISIBILITY);
if ($visibility === null && $config->get(Config::OPTION_RETAIN_VISIBILITY, true)) {
$visibility = $this->visibility($source)->visibility();
}
} catch (Throwable $exception) {
throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
}
$arguments = [
'ACL' => $this->visibility->visibilityToAcl($visibility ?: 'private'),
'Bucket' => $this->bucket,
'Key' => $this->prefixer->prefixPath($destination),
'CopySource' => rawurlencode($this->bucket . '/' . $this->prefixer->prefixPath($source)),
];
try {
$this->client->copyObject($arguments);
} catch (Throwable $exception) {
throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
}
}
/**
* @param string|resource $body
*/
private function upload(string $path, $body, Config $config): void
{
$key = $this->prefixer->prefixPath($path);
$acl = $this->determineAcl($config);
$options = $this->createOptionsFromConfig($config);
$shouldDetermineMimetype = '' !== $body && ! \array_key_exists('ContentType', $options);
if ($shouldDetermineMimetype && $mimeType = $this->mimeTypeDetector->detectMimeType($key, $body)) {
$options['ContentType'] = $mimeType;
}
try {
if ($this->client instanceof SimpleS3Client) {
// Supports upload of files larger than 5GB
$this->client->upload($this->bucket, $key, $body, array_merge($options, ['ACL' => $acl]));
} else {
$this->client->putObject(array_merge($options, [
'Bucket' => $this->bucket,
'Key' => $key,
'Body' => $body,
'ACL' => $acl,
]));
}
} catch (Throwable $exception) {
throw UnableToWriteFile::atLocation($path, $exception->getMessage(), $exception);
}
}
private function determineAcl(Config $config): string
{
$visibility = (string) $config->get(Config::OPTION_VISIBILITY, Visibility::PRIVATE);
return $this->visibility->visibilityToAcl($visibility);
}
private function createOptionsFromConfig(Config $config): array
{
$options = [];
foreach ($this->forwardedOptions as $option) {
$value = $config->get($option, '__NOT_SET__');
if ('__NOT_SET__' !== $value) {
$options[$option] = $value;
}
}
return $options;
}
private function fetchFileMetadata(string $path, string $type): FileAttributes
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
try {
$result = $this->client->headObject($arguments);
$result->resolve();
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::create($path, $type, $exception->getMessage(), $exception);
}
$attributes = $this->mapS3ObjectMetadata($result, $path);
if ( ! $attributes instanceof FileAttributes) {
throw UnableToRetrieveMetadata::create($path, $type, 'Unable to retrieve file attributes, directory attributes received.');
}
return $attributes;
}
/**
* @param HeadObjectOutput|AwsObject|CommonPrefix $item
*/
private function mapS3ObjectMetadata($item, ?string $path = null): StorageAttributes
{
if (null === $path) {
if ($item instanceof AwsObject) {
$path = $this->prefixer->stripPrefix($item->getKey() ?? '');
} elseif ($item instanceof CommonPrefix) {
$path = $this->prefixer->stripPrefix($item->getPrefix() ?? '');
} else {
throw new \RuntimeException(sprintf('Argument 2 of "%s" cannot be null when $item is not instance of "%s" or %s', __METHOD__, AwsObject::class, CommonPrefix::class));
}
}
if ('/' === substr($path, -1)) {
return new DirectoryAttributes(rtrim($path, '/'));
}
$mimeType = null;
$fileSize = null;
$lastModified = null;
$dateTime = null;
$metadata = [];
if ($item instanceof AwsObject) {
$dateTime = $item->getLastModified();
$fileSize = $item->getSize();
} elseif ($item instanceof CommonPrefix) {
// No data available
} elseif ($item instanceof HeadObjectOutput) {
$mimeType = $item->getContentType();
$fileSize = $item->getContentLength();
$dateTime = $item->getLastModified();
$metadata = $this->extractExtraMetadata($item);
} else {
throw new \RuntimeException(sprintf('Object of class "%s" is not supported in %s()', \get_class($item), __METHOD__));
}
if ($dateTime instanceof \DateTimeInterface) {
$lastModified = $dateTime->getTimestamp();
}
return new FileAttributes($path, $fileSize !== null ? (int) $fileSize : null, null, $lastModified, $mimeType, $metadata);
}
/**
* @param HeadObjectOutput $metadata
*/
private function extractExtraMetadata($metadata): array
{
$extracted = [];
foreach ($this->metadataFields as $field) {
$method = 'get' . $field;
if ( ! method_exists($metadata, $method)) {
continue;
}
$value = $metadata->$method();
if (null !== $value) {
$extracted[$field] = $value;
}
}
return $extracted;
}
private function retrievePaginatedListing(array $options): Generator
{
$result = $this->client->listObjectsV2($options);
foreach ($result as $item) {
yield $item;
}
}
private function readObject(string $path): ResultStream
{
$options = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
try {
return $this->client->getObject($options)->getBody();
} catch (Throwable $exception) {
throw UnableToReadFile::fromLocation($path, $exception->getMessage(), $exception);
}
}
private function createObjectIdentifierForXmlRequest(string $key): ObjectIdentifier
{
$escapedKey = htmlentities($key, ENT_XML1 | ENT_QUOTES, 'UTF-8');
if ($escapedKey === '') {
throw new \RuntimeException(sprintf('Cannot escape key "%s" for XML request, htmlentities() returned an empty string.', $key));
}
return new ObjectIdentifier(['Key' => $escapedKey]);
}
public function publicUrl(string $path, Config $config): string
{
if ( ! $this->client instanceof SimpleS3Client) {
throw UnableToGeneratePublicUrl::noGeneratorConfigured($path, 'Client needs to be instance of SimpleS3Client');
}
try {
return $this->client->getUrl($this->bucket, $this->prefixer->prefixPath($path));
} catch (Throwable $exception) {
throw UnableToGeneratePublicUrl::dueToError($path, $exception);
}
}
public function checksum(string $path, Config $config): string
{
$algo = $config->get('checksum_algo', 'etag');
if ($algo !== 'etag') {
throw new ChecksumAlgoIsNotSupported();
}
try {
$metadata = $this->fetchFileMetadata($path, 'checksum')->extraMetadata();
} catch (UnableToRetrieveMetadata $exception) {
throw new UnableToProvideChecksum($exception->reason(), $path, $exception);
}
if ( ! isset($metadata['ETag'])) {
throw new UnableToProvideChecksum('ETag header not available.', $path);
}
return trim($metadata['ETag'], '"');
}
public function temporaryUrl(string $path, DateTimeInterface $expiresAt, Config $config): string
{
try {
$request = new GetObjectRequest([
'Bucket' => $this->bucket,
'Key' => $this->prefixer->prefixPath($path),
] + $config->get('get_object_options', []));
return $this->client->presign($request, DateTimeImmutable::createFromInterface($expiresAt));
} catch (Throwable $exception) {
throw UnableToGenerateTemporaryUrl::dueToError($path, $exception);
}
}
}
================================================
FILE: src/AsyncAwsS3/AsyncAwsS3AdapterTest.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AsyncAwsS3;
use AsyncAws\Core\Exception\Http\ClientException;
use AsyncAws\Core\Exception\Http\NetworkException;
use AsyncAws\Core\Test\Http\SimpleMockedResponse;
use AsyncAws\Core\Test\ResultMockFactory;
use AsyncAws\S3\Result\HeadObjectOutput;
use AsyncAws\S3\Result\ListObjectsV2Output;
use AsyncAws\S3\Result\PutObjectOutput;
use AsyncAws\S3\S3Client;
use AsyncAws\S3\ValueObject\AwsObject;
use AsyncAws\SimpleS3\SimpleS3Client;
use Exception;
use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase;
use League\Flysystem\AwsS3V3\AwsS3V3Adapter;
use League\Flysystem\ChecksumAlgoIsNotSupported;
use League\Flysystem\Config;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\StorageAttributes;
use League\Flysystem\UnableToCheckFileExistence;
use League\Flysystem\UnableToDeleteDirectory;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToListContents;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToRetrieveMetadata;
use League\Flysystem\UnableToWriteFile;
use League\Flysystem\Visibility;
use function getenv;
use function iterator_to_array;
/**
* @group aws
*/
class AsyncAwsS3AdapterTest extends FilesystemAdapterTestCase
{
/**
* @var bool
*/
private $shouldCleanUp = false;
/**
* @var string
*/
private static $adapterPrefix = 'test-prefix';
/**
* @var S3Client|null
*/
private static $s3Client;
/**
* @var S3ClientStub
*/
private static $stubS3Client;
private static function awsConfig(): array
{
$key = getenv('FLYSYSTEM_AWS_S3_KEY');
$secret = getenv('FLYSYSTEM_AWS_S3_SECRET');
$region = getenv('FLYSYSTEM_AWS_S3_REGION') ?: 'eu-central-1';
if ( ! $key || ! $secret) {
self::markTestSkipped('No AWS credentials present for testing.');
}
return [
'accessKeyId' => $key,
'accessKeySecret' => $secret,
'region' => $region,
];
}
protected function setUp(): void
{
parent::setUp();
$this->retryOnException(NetworkException::class);
}
public static function setUpBeforeClass(): void
{
static::$adapterPrefix = 'ci/' . bin2hex(random_bytes(10));
}
protected function tearDown(): void
{
if ( ! $this->shouldCleanUp) {
return;
}
$adapter = $this->adapter();
$adapter->deleteDirectory('/');
/** @var StorageAttributes[] $listing */
$listing = $adapter->listContents('', false);
foreach ($listing as $item) {
if ($item->isFile()) {
$adapter->delete($item->path());
} else {
$adapter->deleteDirectory($item->path());
}
}
}
private static function s3Client(): S3Client
{
if (static::$s3Client instanceof S3Client) {
return static::$s3Client;
}
$bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
if ( ! $bucket) {
self::markTestSkipped('No AWS credentials present for testing.');
}
static::$s3Client = new SimpleS3Client(self::awsConfig());
return static::$s3Client;
}
/**
* @test
*/
public function specifying_a_custom_checksum_algo_is_not_supported(): void
{
/** @var AwsS3V3Adapter $adapter */
$adapter = $this->adapter();
$this->expectException(ChecksumAlgoIsNotSupported::class);
$adapter->checksum('something', new Config(['checksum_algo' => 'md5']));
}
/**
* @test
*
* @see https://github.com/thephpleague/flysystem-aws-s3-v3/issues/287
*/
public function issue_287(): void
{
$adapter = $this->adapter();
$adapter->write('KmFVvKqo/QLMExy2U/620ff60c8a154.pdf', 'pdf content', new Config());
self::assertTrue($adapter->directoryExists('KmFVvKqo'));
}
/**
* @test
*/
public function writing_with_a_specific_mime_type(): void
{
$adapter = $this->adapter();
$adapter->write('some/path.txt', 'contents', new Config(['ContentType' => 'text/plain+special']));
$mimeType = $adapter->mimeType('some/path.txt')->mimeType();
$this->assertEquals('text/plain+special', $mimeType);
}
/**
* @test
*/
public function listing_contents_recursive(): void
{
$adapter = $this->adapter();
$adapter->write('something/0/here.txt', 'contents', new Config());
$adapter->write('something/1/also/here.txt', 'contents', new Config());
$contents = iterator_to_array($adapter->listContents('', true));
$this->assertCount(2, $contents);
$this->assertContainsOnlyInstancesOf(FileAttributes::class, $contents);
/** @var FileAttributes $file */
$file = $contents[0];
$this->assertEquals('something/0/here.txt', $file->path());
/** @var FileAttributes $file */
$file = $contents[1];
$this->assertEquals('something/1/also/here.txt', $file->path());
}
/**
* @test
*/
public function failing_to_delete_while_moving(): void
{
$adapter = $this->adapter();
$adapter->write('source.txt', 'contents to be copied', new Config());
static::$stubS3Client->throwExceptionWhenExecutingCommand('CopyObject');
$this->expectException(UnableToMoveFile::class);
$adapter->move('source.txt', 'destination.txt', new Config());
}
/**
* @test
*/
public function failing_to_delete_a_file(): void
{
$adapter = $this->adapter();
static::$stubS3Client->throwExceptionWhenExecutingCommand('DeleteObject');
$this->expectException(UnableToDeleteFile::class);
$adapter->delete('path.txt');
}
/**
* @test
*/
public function delete_directory_replaces_special_characters_by_xml_entity_codes(): void
{
$this->runScenario(function () {
$directory = 'to-delete';
$object = sprintf('/%s/\'\"&<>.txt', $directory);
$adapter = $this->adapter();
$adapter->write(
$object,
'',
new Config()
);
$adapter->deleteDirectory($directory);
$this->assertFalse($adapter->fileExists($object));
$this->assertFalse($adapter->directoryExists($directory));
});
}
/**
* @test
*/
public function delete_directory_throws_exception_if_object_key_can_not_be_escaped_correctly(): void
{
$listObjectsMock = $this->getMockBuilder(ListObjectsV2Output::class)
->disableOriginalConstructor()
->onlyMethods(['getContents'])
->getMock();
$listObjectsMock->expects(self::once())
->method('getContents')
->willReturn([new AwsObject(['Key' => "\x8F.txt"])]);
$s3Client = $this->getMockBuilder(S3Client::class)
->disableOriginalConstructor()
->onlyMethods(['ListObjectsV2'])
->getMock();
$s3Client->expects(self::once())
->method('ListObjectsV2')
->willReturn($listObjectsMock);
$filesystem = new AsyncAwsS3Adapter($s3Client, 'my-bucket');
$this->expectException(UnableToDeleteDirectory::class);
$this->expectExceptionMessageMatches('/htmlentities\(\) returned an empty string/');
$filesystem->deleteDirectory('directory/containing/objects/with/un-escapable/key');
}
/**
* @test
*/
public function fetching_unknown_mime_type_of_a_file(): void
{
$this->adapter();
$result = ResultMockFactory::create(HeadObjectOutput::class, []);
static::$stubS3Client->stageResultForCommand('HeadObject', $result);
parent::fetching_unknown_mime_type_of_a_file();
}
/**
* @test
*
* @dataProvider dpFailingMetadataGetters
*/
public function failing_to_retrieve_metadata(Exception $exception, string $getterName): void
{
$adapter = $this->adapter();
$result = ResultMockFactory::create(HeadObjectOutput::class, []);
static::$stubS3Client->stageResultForCommand('HeadObject', $result);
$this->expectExceptionObject($exception);
$adapter->{$getterName}('filename.txt');
}
public static function dpFailingMetadataGetters(): iterable
{
yield "mimeType" => [UnableToRetrieveMetadata::mimeType('filename.txt'), 'mimeType'];
yield "lastModified" => [UnableToRetrieveMetadata::lastModified('filename.txt'), 'lastModified'];
yield "fileSize" => [UnableToRetrieveMetadata::fileSize('filename.txt'), 'fileSize'];
}
/**
* @test
*/
public function failing_to_check_for_file_existence(): void
{
$adapter = $this->adapter();
$exception = new ClientException(new SimpleMockedResponse());
static::$stubS3Client->throwExceptionWhenExecutingCommand('ObjectExists', $exception);
$this->expectException(UnableToCheckFileExistence::class);
$adapter->fileExists('something-that-does-exist.txt');
}
/**
* @test
*/
public function configuring_http_streaming_via_options(): void
{
$adapter = $this->useAdapter($this->createFilesystemAdapter());
$this->givenWeHaveAnExistingFile('path.txt');
$resource = $adapter->readStream('path.txt');
$metadata = stream_get_meta_data($resource);
fclose($resource);
$this->assertTrue($metadata['seekable']);
}
/**
* @test
*/
public function write_with_s3_client(): void
{
$file = 'foo/bar.txt';
$prefix = 'all-files';
$bucket = 'foobar';
$contents = 'contents';
$s3Client = $this->getMockBuilder(S3Client::class)
->disableOriginalConstructor()
->onlyMethods(['putObject'])
->getMock();
$s3Client->expects(self::once())
->method('putObject')
->with(self::callback(function (array $input) use ($file, $prefix, $bucket, $contents) {
if ($input['Key'] !== $prefix . '/' . $file) {
return false;
}
if ($contents !== $input['Body']) {
return false;
}
if ($input['Bucket'] !== $bucket) {
return false;
}
return true;
}))->willReturn(ResultMockFactory::create(PutObjectOutput::class));
$filesystem = new AsyncAwsS3Adapter($s3Client, $bucket, $prefix);
$filesystem->write($file, $contents, new Config());
}
/**
* @test
*/
public function write_with_simple_s3_client(): void
{
$file = 'foo/bar.txt';
$prefix = 'all-files';
$bucket = 'foobar';
$contents = 'contents';
$s3Client = $this->getMockBuilder(SimpleS3Client::class)
->disableOriginalConstructor()
->onlyMethods(['upload', 'putObject'])
->getMock();
$s3Client->expects(self::never())->method('putObject');
$s3Client->expects(self::once())
->method('upload')
->with($bucket, $prefix . '/' . $file, $contents);
$filesystem = new AsyncAwsS3Adapter($s3Client, $bucket, $prefix);
$filesystem->write($file, $contents, new Config());
}
/**
* @test
*/
public function failing_to_write_a_file(): void
{
$adapter = $this->adapter();
static::$stubS3Client->throwExceptionWhenExecutingCommand('PutObject');
$this->expectException(UnableToWriteFile::class);
$adapter->write('foo/bar.txt', 'contents', new Config());
}
/**
* @test
*/
public function moving_a_file_with_visibility(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->move('source.txt', 'destination.txt', new Config([Config::OPTION_VISIBILITY => Visibility::PRIVATE]));
$this->assertFalse(
$adapter->fileExists('source.txt'),
'After moving a file should no longer exist in the original location.'
);
$this->assertTrue(
$adapter->fileExists('destination.txt'),
'After moving, a file should be present at the new location.'
);
$this->assertEquals(Visibility::PRIVATE, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
/**
* @test
*/
public function copying_a_file_with_visibility(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->copy('source.txt', 'destination.txt', new Config([Config::OPTION_VISIBILITY => Visibility::PRIVATE]));
$this->assertTrue($adapter->fileExists('source.txt'));
$this->assertTrue($adapter->fileExists('destination.txt'));
$this->assertEquals(Visibility::PRIVATE, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
/**
* @test
*/
public function copying_a_file_with_non_ascii_characters(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'ıÇöü🤔.txt',
'contents to be copied',
new Config()
);
$adapter->copy('ıÇöü🤔.txt', 'ıÇöü🤔_copy.txt', new Config());
$this->assertTrue($adapter->fileExists('ıÇöü🤔.txt'));
$this->assertTrue($adapter->fileExists('ıÇöü🤔_copy.txt'));
$this->assertEquals('contents to be copied', $adapter->read('ıÇöü🤔_copy.txt'));
});
}
/**
* @test
*/
public function top_level_directory_excluded_from_listing(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write('directory/file.txt', '', new Config());
$adapter->createDirectory('empty', new Config());
$adapter->createDirectory('nested/nested', new Config());
$listing1 = iterator_to_array($adapter->listContents('directory', true));
$listing2 = iterator_to_array($adapter->listContents('empty', true));
$listing3 = iterator_to_array($adapter->listContents('nested', true));
self::assertCount(1, $listing1);
self::assertCount(0, $listing2);
self::assertCount(1, $listing3);
});
}
/**
* @test
*/
public function failing_to_list_contents(): void
{
$adapter = $this->adapter();
static::$stubS3Client->throwExceptionWhenExecutingCommand('ListObjectsV2');
$this->expectException(UnableToListContents::class);
iterator_to_array($adapter->listContents('/path', false));
}
protected static function createFilesystemAdapter(): FilesystemAdapter
{
static::$stubS3Client = new S3ClientStub(static::s3Client(), self::awsConfig());
/** @var string $bucket */
$bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
$prefix = getenv('FLYSYSTEM_AWS_S3_PREFIX') ?: static::$adapterPrefix;
return new AsyncAwsS3Adapter(static::$stubS3Client, $bucket, $prefix, null, null);
}
}
================================================
FILE: src/AsyncAwsS3/LICENSE
================================================
Copyright (c) 2013-2026 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.
================================================
FILE: src/AsyncAwsS3/PortableVisibilityConverter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AsyncAwsS3;
use AsyncAws\S3\ValueObject\Grant;
use League\Flysystem\Visibility;
class PortableVisibilityConverter implements VisibilityConverter
{
private const PUBLIC_GRANTEE_URI = 'http://acs.amazonaws.com/groups/global/AllUsers';
private const PUBLIC_GRANTS_PERMISSION = 'READ';
private const PUBLIC_ACL = 'public-read';
private const PRIVATE_ACL = 'private';
/**
* @var string
*/
private $defaultForDirectories;
public function __construct(string $defaultForDirectories = Visibility::PUBLIC)
{
$this->defaultForDirectories = $defaultForDirectories;
}
public function visibilityToAcl(string $visibility): string
{
if (Visibility::PUBLIC === $visibility) {
return self::PUBLIC_ACL;
}
return self::PRIVATE_ACL;
}
/**
* @param Grant[] $grants
*/
public function aclToVisibility(array $grants): string
{
foreach ($grants as $grant) {
if (null === $grantee = $grant->getGrantee()) {
continue;
}
$granteeUri = $grantee->getURI();
$permission = $grant->getPermission();
if (self::PUBLIC_GRANTEE_URI === $granteeUri && self::PUBLIC_GRANTS_PERMISSION === $permission) {
return Visibility::PUBLIC;
}
}
return Visibility::PRIVATE;
}
public function defaultForDirectories(): string
{
return $this->defaultForDirectories;
}
}
================================================
FILE: src/AsyncAwsS3/README.md
================================================
## Sub-split of Flysystem for AsyncAws S3.
> ⚠️ this is a sub-split, for pull requests and issues, visit: https://github.com/thephpleague/flysystem
```bash
composer require league/flysystem-async-aws-s3
```
View the [documentation](https://flysystem.thephpleague.com/docs/adapter/async-aws-s3/)
================================================
FILE: src/AsyncAwsS3/S3ClientStub.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AsyncAwsS3;
use AsyncAws\Core\Exception\Exception;
use AsyncAws\Core\Exception\Http\NetworkException;
use AsyncAws\Core\Result;
use AsyncAws\S3\Input\CopyObjectRequest;
use AsyncAws\S3\Input\DeleteObjectRequest;
use AsyncAws\S3\Input\DeleteObjectsRequest;
use AsyncAws\S3\Input\GetObjectAclRequest;
use AsyncAws\S3\Input\GetObjectRequest;
use AsyncAws\S3\Input\HeadObjectRequest;
use AsyncAws\S3\Input\ListObjectsV2Request;
use AsyncAws\S3\Input\PutObjectAclRequest;
use AsyncAws\S3\Input\PutObjectRequest;
use AsyncAws\S3\Result\CopyObjectOutput;
use AsyncAws\S3\Result\DeleteObjectOutput;
use AsyncAws\S3\Result\DeleteObjectsOutput;
use AsyncAws\S3\Result\GetObjectAclOutput;
use AsyncAws\S3\Result\GetObjectOutput;
use AsyncAws\S3\Result\HeadObjectOutput;
use AsyncAws\S3\Result\ListObjectsV2Output;
use AsyncAws\S3\Result\ObjectExistsWaiter;
use AsyncAws\S3\Result\PutObjectAclOutput;
use AsyncAws\S3\Result\PutObjectOutput;
use AsyncAws\S3\S3Client;
use AsyncAws\SimpleS3\SimpleS3Client;
use DateTimeImmutable;
use Symfony\Component\HttpClient\MockHttpClient;
/**
* @codeCoverageIgnore
*/
class S3ClientStub extends SimpleS3Client
{
/**
* @var S3Client
*/
private $actualClient;
/**
* @var Exception[]
*/
private $stagedExceptions = [];
/**
* @var Result[]
*/
private $stagedResult = [];
public function __construct(SimpleS3Client $client, $configuration = [])
{
$this->actualClient = $client;
parent::__construct($configuration, null, new MockHttpClient());
}
public function throwExceptionWhenExecutingCommand(string $commandName, ?Exception $exception = null): void
{
$this->stagedExceptions[$commandName] = $exception ?? new NetworkException();
}
public function stageResultForCommand(string $commandName, Result $result): void
{
$this->stagedResult[$commandName] = $result;
}
private function getStagedResult(string $name): ?Result
{
if (array_key_exists($name, $this->stagedExceptions)) {
$exception = $this->stagedExceptions[$name];
unset($this->stagedExceptions[$name]);
throw $exception;
}
if (array_key_exists($name, $this->stagedResult)) {
$result = $this->stagedResult[$name];
unset($this->stagedResult[$name]);
return $result;
}
return null;
}
/**
* @param array|CopyObjectRequest $input
*/
public function copyObject($input): CopyObjectOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('CopyObject') ?? $this->actualClient->copyObject($input);
}
/**
* @param array|DeleteObjectRequest $input
*/
public function deleteObject($input): DeleteObjectOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('DeleteObject') ?? $this->actualClient->deleteObject($input);
}
/**
* @param array|HeadObjectRequest $input
*/
public function headObject($input): HeadObjectOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('HeadObject') ?? $this->actualClient->headObject($input);
}
/**
* @param array|HeadObjectRequest $input
*/
public function objectExists($input): ObjectExistsWaiter
{
// @phpstan-ignore-next-line
return $this->getStagedResult('ObjectExists') ?? $this->actualClient->objectExists($input);
}
/**
* @param array|ListObjectsV2Request $input
*/
public function listObjectsV2($input): ListObjectsV2Output
{
// @phpstan-ignore-next-line
return $this->getStagedResult('ListObjectsV2') ?? $this->actualClient->listObjectsV2($input);
}
/**
* @param array|DeleteObjectsRequest $input
*/
public function deleteObjects($input): DeleteObjectsOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('DeleteObjects') ?? $this->actualClient->deleteObjects($input);
}
/**
* @param array|GetObjectAclRequest $input
*/
public function getObjectAcl($input): GetObjectAclOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('GetObjectAcl') ?? $this->actualClient->getObjectAcl($input);
}
/**
* @param array|PutObjectAclRequest $input
*/
public function putObjectAcl($input): PutObjectAclOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('PutObjectAcl') ?? $this->actualClient->putObjectAcl($input);
}
/**
* @param array|PutObjectRequest $input
*/
public function putObject($input): PutObjectOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('PutObject') ?? $this->actualClient->putObject($input);
}
/**
* @param array|GetObjectRequest $input
*/
public function getObject($input): GetObjectOutput
{
// @phpstan-ignore-next-line
return $this->getStagedResult('GetObject') ?? $this->actualClient->getObject($input);
}
public function getUrl(string $bucket, string $key): string
{
return $this->actualClient->getUrl($bucket, $key);
}
public function getPresignedUrl(string $bucket, string $key, ?DateTimeImmutable $expires = null, ?string $versionId = null): string
{
return $this->actualClient->getPresignedUrl($bucket, $key, $expires);
}
}
================================================
FILE: src/AsyncAwsS3/VisibilityConverter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AsyncAwsS3;
use AsyncAws\S3\ValueObject\Grant;
interface VisibilityConverter
{
public function visibilityToAcl(string $visibility): string;
/**
* @param Grant[] $grants
*/
public function aclToVisibility(array $grants): string;
public function defaultForDirectories(): string;
}
================================================
FILE: src/AsyncAwsS3/composer.json
================================================
{
"name": "league/flysystem-async-aws-s3",
"description": "AsyncAws S3 filesystem adapter for Flysystem.",
"keywords": ["async-aws","aws", "s3", "flysystem", "filesystem", "storage", "file", "files"],
"type": "library",
"autoload": {
"psr-4": {
"League\\Flysystem\\AsyncAwsS3\\": ""
}
},
"require": {
"php": "^8.0.2",
"league/flysystem": "^3.10.0",
"league/mime-type-detection": "^1.0.0",
"async-aws/s3": "^1.5 || ^2.0 || ^3.0"
},
"require-dev": {
"async-aws/simple-s3": "^2.1"
},
"conflict": {
"symfony/http-client": "<5.2"
},
"license": "MIT",
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frankdejonge.nl"
}
]
}
================================================
FILE: src/AwsS3V3/.gitattributes
================================================
* text=auto
.github export-ignore
.gitattributes export-ignore
.gitignore export-ignore
**/*Test.php export-ignore
**/*Stub.php export-ignore
README.md export-ignore
================================================
FILE: src/AwsS3V3/.github/workflows/close-subsplit-prs.yaml
================================================
---
name: Close sub-split PRs
on:
push:
branches:
- 2.x
- 3.x
pull_request:
branches:
- 2.x
- 3.x
schedule:
- cron: '30 7 * * *'
jobs:
close_subsplit_prs:
runs-on: ubuntu-latest
name: Close sub-split PRs
steps:
- uses: frankdejonge/action-close-subsplit-pr@0.1.0
with:
close_pr: 'yes'
target_branch_match: '^(?!master).+$'
message: |
Hi :wave:,
Thank you for contributing to Flysystem. Unfortunately, you've sent a PR to a read-only sub-split repository.
All pull requests should be directed towards: https://github.com/thephpleague/flysystem
================================================
FILE: src/AwsS3V3/AwsS3V3Adapter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AwsS3V3;
use Aws\Api\DateTimeResult;
use Aws\S3\S3ClientInterface;
use DateTimeInterface;
use Generator;
use League\Flysystem\ChecksumAlgoIsNotSupported;
use League\Flysystem\ChecksumProvider;
use League\Flysystem\Config;
use League\Flysystem\DirectoryAttributes;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\FilesystemOperationFailed;
use League\Flysystem\PathPrefixer;
use League\Flysystem\StorageAttributes;
use League\Flysystem\UnableToCheckDirectoryExistence;
use League\Flysystem\UnableToCheckFileExistence;
use League\Flysystem\UnableToCopyFile;
use League\Flysystem\UnableToDeleteDirectory;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToGeneratePublicUrl;
use League\Flysystem\UnableToGenerateTemporaryUrl;
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\UrlGeneration\PublicUrlGenerator;
use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
use League\Flysystem\Visibility;
use League\MimeTypeDetection\FinfoMimeTypeDetector;
use League\MimeTypeDetection\MimeTypeDetector;
use Psr\Http\Message\StreamInterface;
use Throwable;
use function trim;
class AwsS3V3Adapter implements FilesystemAdapter, PublicUrlGenerator, ChecksumProvider, TemporaryUrlGenerator
{
/**
* @var string[]
*/
public const AVAILABLE_OPTIONS = [
'ACL',
'CacheControl',
'ContentDisposition',
'ContentEncoding',
'ContentLength',
'ContentType',
'Expires',
'GrantFullControl',
'GrantRead',
'GrantReadACP',
'GrantWriteACP',
'Metadata',
'MetadataDirective',
'RequestPayer',
'SSECustomerAlgorithm',
'SSECustomerKey',
'SSECustomerKeyMD5',
'SSEKMSKeyId',
'ServerSideEncryption',
'StorageClass',
'Tagging',
'WebsiteRedirectLocation',
'ChecksumAlgorithm',
'CopySourceSSECustomerAlgorithm',
'CopySourceSSECustomerKey',
'CopySourceSSECustomerKeyMD5',
];
/**
* @var string[]
*/
public const MUP_AVAILABLE_OPTIONS = [
'add_content_md5',
'before_upload',
'concurrency',
'mup_threshold',
'params',
'part_size',
];
/**
* @var string[]
*/
private const EXTRA_METADATA_FIELDS = [
'Metadata',
'StorageClass',
'ETag',
'VersionId',
];
private PathPrefixer $prefixer;
private VisibilityConverter $visibility;
private MimeTypeDetector $mimeTypeDetector;
public function __construct(
private S3ClientInterface $client,
private string $bucket,
string $prefix = '',
?VisibilityConverter $visibility = null,
?MimeTypeDetector $mimeTypeDetector = null,
private array $options = [],
private bool $streamReads = true,
private array $forwardedOptions = self::AVAILABLE_OPTIONS,
private array $metadataFields = self::EXTRA_METADATA_FIELDS,
private array $multipartUploadOptions = self::MUP_AVAILABLE_OPTIONS,
) {
$this->prefixer = new PathPrefixer($prefix);
$this->visibility = $visibility ?? new PortableVisibilityConverter();
$this->mimeTypeDetector = $mimeTypeDetector ?? new FinfoMimeTypeDetector();
}
public function fileExists(string $path): bool
{
try {
return $this->client->doesObjectExistV2($this->bucket, $this->prefixer->prefixPath($path), false, $this->options);
} catch (Throwable $exception) {
throw UnableToCheckFileExistence::forLocation($path, $exception);
}
}
public function directoryExists(string $path): bool
{
try {
$prefix = $this->prefixer->prefixDirectoryPath($path);
$options = ['Bucket' => $this->bucket, 'Prefix' => $prefix, 'MaxKeys' => 1, 'Delimiter' => '/'];
$command = $this->client->getCommand('ListObjectsV2', $options);
$result = $this->client->execute($command);
return $result->hasKey('Contents') || $result->hasKey('CommonPrefixes');
} catch (Throwable $exception) {
throw UnableToCheckDirectoryExistence::forLocation($path, $exception);
}
}
public function write(string $path, string $contents, Config $config): void
{
$this->upload($path, $contents, $config);
}
/**
* @param string $path
* @param string|resource $body
* @param Config $config
*/
private function upload(string $path, $body, Config $config): void
{
$key = $this->prefixer->prefixPath($path);
$options = $this->createOptionsFromConfig($config);
$acl = $options['params']['ACL'] ?? $this->determineAcl($config);
$shouldDetermineMimetype = ! array_key_exists('ContentType', $options['params']);
if ($shouldDetermineMimetype && $mimeType = $this->mimeTypeDetector->detectMimeType($key, $body)) {
$options['params']['ContentType'] = $mimeType;
}
try {
$this->client->upload($this->bucket, $key, $body, $acl, $options);
} catch (Throwable $exception) {
throw UnableToWriteFile::atLocation($path, $exception->getMessage(), $exception);
}
}
private function determineAcl(Config $config): string
{
$visibility = (string) $config->get(Config::OPTION_VISIBILITY, Visibility::PRIVATE);
return $this->visibility->visibilityToAcl($visibility);
}
private function createOptionsFromConfig(Config $config): array
{
$config = $config->withDefaults($this->options);
$options = ['params' => []];
if ($mimetype = $config->get('mimetype')) {
$options['params']['ContentType'] = $mimetype;
}
foreach ($this->forwardedOptions as $option) {
$value = $config->get($option, '__NOT_SET__');
if ($value !== '__NOT_SET__') {
$options['params'][$option] = $value;
}
}
foreach ($this->multipartUploadOptions as $option) {
$value = $config->get($option, '__NOT_SET__');
if ($value !== '__NOT_SET__') {
$options[$option] = $value;
}
}
return $options;
}
public function writeStream(string $path, $contents, Config $config): void
{
$this->upload($path, $contents, $config);
}
public function read(string $path): string
{
$body = $this->readObject($path, false);
return (string) $body->getContents();
}
public function readStream(string $path)
{
/** @var resource $resource */
$resource = $this->readObject($path, true)->detach();
return $resource;
}
public function delete(string $path): void
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
$command = $this->client->getCommand('DeleteObject', $arguments);
try {
$this->client->execute($command);
} catch (Throwable $exception) {
throw UnableToDeleteFile::atLocation($path, '', $exception);
}
}
public function deleteDirectory(string $path): void
{
$prefix = $this->prefixer->prefixPath($path);
$prefix = ltrim(rtrim($prefix, '/') . '/', '/');
try {
$this->client->deleteMatchingObjects($this->bucket, $prefix);
} catch (Throwable $exception) {
throw UnableToDeleteDirectory::atLocation($path, '', $exception);
}
}
public function createDirectory(string $path, Config $config): void
{
$defaultVisibility = $config->get(Config::OPTION_DIRECTORY_VISIBILITY, $this->visibility->defaultForDirectories());
$config = $config->withDefaults([Config::OPTION_VISIBILITY => $defaultVisibility]);
$this->upload(rtrim($path, '/') . '/', '', $config);
}
public function setVisibility(string $path, string $visibility): void
{
$arguments = [
'Bucket' => $this->bucket,
'Key' => $this->prefixer->prefixPath($path),
'ACL' => $this->visibility->visibilityToAcl($visibility),
];
$command = $this->client->getCommand('PutObjectAcl', $arguments);
try {
$this->client->execute($command);
} catch (Throwable $exception) {
throw UnableToSetVisibility::atLocation($path, '', $exception);
}
}
public function visibility(string $path): FileAttributes
{
$arguments = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
$command = $this->client->getCommand('GetObjectAcl', $arguments);
try {
$result = $this->client->execute($command);
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::visibility($path, '', $exception);
}
$visibility = $this->visibility->aclToVisibility((array) $result->get('Grants'));
return new FileAttributes($path, null, $visibility);
}
private function fetchFileMetadata(string $path, string $type): FileAttributes
{
$options = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
$command = $this->client->getCommand('HeadObject', $options + $this->options);
try {
$result = $this->client->execute($command);
} catch (Throwable $exception) {
throw UnableToRetrieveMetadata::create($path, $type, '', $exception);
}
$attributes = $this->mapS3ObjectMetadata($result->toArray(), $path);
if ( ! $attributes instanceof FileAttributes) {
throw UnableToRetrieveMetadata::create($path, $type, '');
}
return $attributes;
}
private function mapS3ObjectMetadata(array $metadata, string $path): StorageAttributes
{
if (substr($path, -1) === '/') {
return new DirectoryAttributes(rtrim($path, '/'));
}
$mimetype = $metadata['ContentType'] ?? null;
$fileSize = $metadata['ContentLength'] ?? $metadata['Size'] ?? null;
$fileSize = $fileSize === null ? null : (int) $fileSize;
$dateTime = $metadata['LastModified'] ?? null;
$lastModified = $dateTime instanceof DateTimeResult ? $dateTime->getTimeStamp() : null;
return new FileAttributes(
$path,
$fileSize,
null,
$lastModified,
$mimetype,
$this->extractExtraMetadata($metadata)
);
}
private function extractExtraMetadata(array $metadata): array
{
$extracted = [];
foreach ($this->metadataFields as $field) {
if (isset($metadata[$field]) && $metadata[$field] !== '') {
$extracted[$field] = $metadata[$field];
}
}
return $extracted;
}
public function mimeType(string $path): FileAttributes
{
$attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_MIME_TYPE);
if ($attributes->mimeType() === null) {
throw UnableToRetrieveMetadata::mimeType($path);
}
return $attributes;
}
public function lastModified(string $path): FileAttributes
{
$attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_LAST_MODIFIED);
if ($attributes->lastModified() === null) {
throw UnableToRetrieveMetadata::lastModified($path);
}
return $attributes;
}
public function fileSize(string $path): FileAttributes
{
$attributes = $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_FILE_SIZE);
if ($attributes->fileSize() === null) {
throw UnableToRetrieveMetadata::fileSize($path);
}
return $attributes;
}
public function listContents(string $path, bool $deep): iterable
{
$prefix = trim($this->prefixer->prefixPath($path), '/');
$prefix = $prefix === '' ? '' : $prefix . '/';
$options = ['Bucket' => $this->bucket, 'Prefix' => $prefix];
if ($deep === false) {
$options['Delimiter'] = '/';
}
$listing = $this->retrievePaginatedListing($options);
foreach ($listing as $item) {
$key = $item['Key'] ?? $item['Prefix'];
if ($key === $prefix) {
continue;
}
yield $this->mapS3ObjectMetadata($item, $this->prefixer->stripPrefix($key));
}
}
private function retrievePaginatedListing(array $options): Generator
{
$resultPaginator = $this->client->getPaginator('ListObjectsV2', $options + $this->options);
foreach ($resultPaginator as $result) {
yield from ($result->get('CommonPrefixes') ?? []);
yield from ($result->get('Contents') ?? []);
}
}
public function move(string $source, string $destination, Config $config): void
{
if ($source === $destination) {
return;
}
try {
$this->copy($source, $destination, $config);
$this->delete($source);
} catch (FilesystemOperationFailed $exception) {
throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
}
}
public function copy(string $source, string $destination, Config $config): void
{
if ($source === $destination) {
return;
}
try {
$visibility = $config->get(Config::OPTION_VISIBILITY);
if ($visibility === null && $config->get(Config::OPTION_RETAIN_VISIBILITY, true)) {
$visibility = $this->visibility($source)->visibility();
}
} catch (Throwable $exception) {
throw UnableToCopyFile::fromLocationTo(
$source,
$destination,
$exception
);
}
$options = $this->createOptionsFromConfig($config);
$options['MetadataDirective'] = $config->get('MetadataDirective', 'COPY');
try {
$this->client->copy(
$this->bucket,
$this->prefixer->prefixPath($source),
$this->bucket,
$this->prefixer->prefixPath($destination),
$this->visibility->visibilityToAcl($visibility ?: 'private'),
$options,
);
} catch (Throwable $exception) {
throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
}
}
private function readObject(string $path, bool $wantsStream): StreamInterface
{
$options = ['Bucket' => $this->bucket, 'Key' => $this->prefixer->prefixPath($path)];
if ($wantsStream && $this->streamReads && ! isset($this->options['@http']['stream'])) {
$options['@http']['stream'] = true;
}
$command = $this->client->getCommand('GetObject', $options + $this->options);
try {
return $this->client->execute($command)->get('Body');
} catch (Throwable $exception) {
throw UnableToReadFile::fromLocation($path, '', $exception);
}
}
public function publicUrl(string $path, Config $config): string
{
$location = $this->prefixer->prefixPath($path);
try {
return $this->client->getObjectUrl($this->bucket, $location);
} catch (Throwable $exception) {
throw UnableToGeneratePublicUrl::dueToError($path, $exception);
}
}
public function checksum(string $path, Config $config): string
{
$algo = $config->get('checksum_algo', 'etag');
if ($algo !== 'etag') {
throw new ChecksumAlgoIsNotSupported();
}
try {
$metadata = $this->fetchFileMetadata($path, 'checksum')->extraMetadata();
} catch (UnableToRetrieveMetadata $exception) {
throw new UnableToProvideChecksum($exception->reason(), $path, $exception);
}
if ( ! isset($metadata['ETag'])) {
throw new UnableToProvideChecksum('ETag header not available.', $path);
}
return trim($metadata['ETag'], '"');
}
public function temporaryUrl(string $path, DateTimeInterface $expiresAt, Config $config): string
{
try {
$options = $config->get('get_object_options', []);
$command = $this->client->getCommand('GetObject', [
'Bucket' => $this->bucket,
'Key' => $this->prefixer->prefixPath($path),
] + $options);
$presignedRequestOptions = $config->get('presigned_request_options', []);
$request = $this->client->createPresignedRequest($command, $expiresAt, $presignedRequestOptions);
return (string) $request->getUri();
} catch (Throwable $exception) {
throw UnableToGenerateTemporaryUrl::dueToError($path, $exception);
}
}
}
================================================
FILE: src/AwsS3V3/AwsS3V3AdapterTest.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AwsS3V3;
use Aws\Result;
use Aws\S3\S3Client;
use Aws\S3\S3ClientInterface;
use Exception;
use Generator;
use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase;
use League\Flysystem\ChecksumAlgoIsNotSupported;
use League\Flysystem\Config;
use League\Flysystem\FileAttributes;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\PathPrefixer;
use League\Flysystem\StorageAttributes;
use League\Flysystem\UnableToCheckFileExistence;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToRetrieveMetadata;
use League\Flysystem\UnableToWriteFile;
use League\Flysystem\Visibility;
use RuntimeException;
use function getenv;
use function iterator_to_array;
/**
* @group aws
*/
class AwsS3V3AdapterTest extends FilesystemAdapterTestCase
{
/**
* @var bool
*/
private $shouldCleanUp = false;
/**
* @var string
*/
private static $adapterPrefix = 'test-prefix';
/**
* @var S3ClientInterface|null
*/
private static $s3Client;
/**
* @var S3ClientStub
*/
private static $stubS3Client;
public static function setUpBeforeClass(): void
{
static::$adapterPrefix = getenv('FLYSYSTEM_AWS_S3_PREFIX') ?: 'ci/' . bin2hex(random_bytes(10));
}
protected function tearDown(): void
{
if ( ! $this->shouldCleanUp) {
return;
}
$adapter = $this->adapter();
$adapter->deleteDirectory('/');
/** @var StorageAttributes[] $listing */
$listing = $adapter->listContents('', false);
foreach ($listing as $item) {
if ($item->isFile()) {
$adapter->delete($item->path());
} else {
$adapter->deleteDirectory($item->path());
}
}
self::$adapter = null;
}
protected function setUp(): void
{
if (PHP_VERSION_ID < 80100) {
$this->markTestSkipped('AWS does not support this anymore.');
}
parent::setUp();
}
private static function s3Client(): S3ClientInterface
{
if (static::$s3Client instanceof S3ClientInterface) {
return static::$s3Client;
}
$key = getenv('FLYSYSTEM_AWS_S3_KEY');
$secret = getenv('FLYSYSTEM_AWS_S3_SECRET');
$bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
$region = getenv('FLYSYSTEM_AWS_S3_REGION') ?: 'eu-central-1';
if ( ! $key || ! $secret || ! $bucket) {
self::markTestSkipped('No AWS credentials present for testing.');
}
$options = ['version' => 'latest', 'credentials' => compact('key', 'secret'), 'region' => $region];
return static::$s3Client = new S3Client($options);
}
/**
* @test
*/
public function writing_with_a_specific_mime_type(): void
{
$adapter = $this->adapter();
$adapter->write('some/path.txt', 'contents', new Config(['ContentType' => 'text/plain+special']));
$mimeType = $adapter->mimeType('some/path.txt')->mimeType();
$this->assertEquals('text/plain+special', $mimeType);
}
/**
* @test
*/
public function writing_a_file_with_explicit_mime_type(): void
{
$adapter = $this->adapter();
$adapter->write('some/path.txt', 'contents', new Config(['mimetype' => 'text/plain+special']));
$mimeType = $adapter->mimeType('some/path.txt')->mimeType();
$this->assertEquals('text/plain+special', $mimeType);
}
/**
* @test
*
* @see https://github.com/thephpleague/flysystem-aws-s3-v3/issues/291
*/
public function issue_291(): void
{
$adapter = $this->adapter();
$adapter->createDirectory('directory', new Config());
$listing = iterator_to_array($adapter->listContents('directory', true));
self::assertCount(0, $listing);
}
/**
* @test
*/
public function listing_contents_recursive(): void
{
$adapter = $this->adapter();
$adapter->write('something/0/here.txt', 'contents', new Config());
$adapter->write('something/1/also/here.txt', 'contents', new Config());
$contents = iterator_to_array($adapter->listContents('', true));
$this->assertCount(2, $contents);
$this->assertContainsOnlyInstancesOf(FileAttributes::class, $contents);
/** @var FileAttributes $file */
$file = $contents[0];
$this->assertEquals('something/0/here.txt', $file->path());
/** @var FileAttributes $file */
$file = $contents[1];
$this->assertEquals('something/1/also/here.txt', $file->path());
}
/**
* @test
*/
public function failing_to_delete_while_moving(): void
{
$adapter = $this->adapter();
$adapter->write('source.txt', 'contents to be copied', new Config());
static::$stubS3Client->failOnNextCopy();
$this->expectException(UnableToMoveFile::class);
$adapter->move('source.txt', 'destination.txt', new Config());
}
/**
* @test
*
* @see https://github.com/thephpleague/flysystem-aws-s3-v3/issues/287
*/
public function issue_287(): void
{
$adapter = $this->adapter();
$adapter->write('KmFVvKqo/QLMExy2U/620ff60c8a154.pdf', 'pdf content', new Config());
self::assertTrue($adapter->directoryExists('KmFVvKqo'));
}
/**
* @test
*/
public function failing_to_write_a_file(): void
{
$adapter = $this->adapter();
static::$stubS3Client->throwDuringUpload(new RuntimeException('Oh no'));
$this->expectException(UnableToWriteFile::class);
$adapter->write('path.txt', 'contents', new Config());
}
/**
* @test
*/
public function failing_to_delete_a_file(): void
{
$adapter = $this->adapter();
static::$stubS3Client->throwExceptionWhenExecutingCommand('DeleteObject');
$this->expectException(UnableToDeleteFile::class);
$adapter->delete('path.txt');
}
/**
* @test
*/
public function fetching_unknown_mime_type_of_a_file(): void
{
$this->adapter();
$result = new Result([
'Key' => static::$adapterPrefix . '/unknown-mime-type.md5',
]);
static::$stubS3Client->stageResultForCommand('HeadObject', $result);
parent::fetching_unknown_mime_type_of_a_file();
}
/**
* @test
*
* @dataProvider dpFailingMetadataGetters
*/
public function failing_to_retrieve_metadata(Exception $exception, string $getterName): void
{
$adapter = $this->adapter();
$result = new Result([
'Key' => static::$adapterPrefix . '/filename.txt',
]);
static::$stubS3Client->stageResultForCommand('HeadObject', $result);
$this->expectExceptionObject($exception);
$adapter->{$getterName}('filename.txt');
}
public static function dpFailingMetadataGetters(): iterable
{
yield "mimeType" => [UnableToRetrieveMetadata::mimeType('filename.txt'), 'mimeType'];
yield "lastModified" => [UnableToRetrieveMetadata::lastModified('filename.txt'), 'lastModified'];
yield "fileSize" => [UnableToRetrieveMetadata::fileSize('filename.txt'), 'fileSize'];
}
/**
* @test
*/
public function failing_to_check_for_file_existence(): void
{
$adapter = $this->adapter();
static::$stubS3Client->throw500ExceptionWhenExecutingCommand('HeadObject');
$this->expectException(UnableToCheckFileExistence::class);
$adapter->fileExists('something-that-does-exist.txt');
}
/**
* @test
*
* @dataProvider casesWhereHttpStreamingInfluencesSeekability
*/
public function streaming_reads_are_not_seekable_and_non_streaming_are(bool $streaming, bool $seekable): void
{
if (getenv('COMPOSER_OPTS') === '--prefer-lowest') {
$this->markTestSkipped('The SDK does not support streaming in low versions.');
}
$adapter = $this->useAdapter($this->createFilesystemAdapter($streaming));
$this->givenWeHaveAnExistingFile('path.txt');
$resource = $adapter->readStream('path.txt');
$metadata = stream_get_meta_data($resource);
fclose($resource);
$this->assertEquals($seekable, $metadata['seekable']);
}
public static function casesWhereHttpStreamingInfluencesSeekability(): Generator
{
yield "not streaming reads have seekable stream" => [false, true];
yield "streaming reads have non-seekable stream" => [true, false];
}
/**
* @test
*
* @dataProvider casesWhereHttpStreamingInfluencesSeekability
*/
public function configuring_http_streaming_via_options(bool $streaming): void
{
$adapter = $this->useAdapter($this->createFilesystemAdapter($streaming, ['@http' => ['stream' => false]]));
$this->givenWeHaveAnExistingFile('path.txt');
$resource = $adapter->readStream('path.txt');
$metadata = stream_get_meta_data($resource);
fclose($resource);
$this->assertTrue($metadata['seekable']);
}
/**
* @test
*
* @dataProvider casesWhereHttpStreamingInfluencesSeekability
*/
public function use_globally_configured_options(bool $streaming): void
{
$adapter = $this->useAdapter($this->createFilesystemAdapter($streaming, ['ContentType' => 'text/plain+special']));
$this->givenWeHaveAnExistingFile('path.txt');
$mimeType = $adapter->mimeType('path.txt')->mimeType();
$this->assertSame('text/plain+special', $mimeType);
}
/**
* @test
*/
public function moving_with_updated_metadata(): void
{
$adapter = $this->adapter();
$adapter->write('source.txt', 'contents to be moved', new Config(['ContentType' => 'text/plain']));
$mimeTypeSource = $adapter->mimeType('source.txt')->mimeType();
$this->assertSame('text/plain', $mimeTypeSource);
$adapter->move('source.txt', 'destination.txt', new Config(
['ContentType' => 'text/plain+special', 'MetadataDirective' => 'REPLACE']
));
$mimeTypeDestination = $adapter->mimeType('destination.txt')->mimeType();
$this->assertSame('text/plain+special', $mimeTypeDestination);
}
/**
* @test
*/
public function moving_without_updated_metadata(): void
{
$adapter = $this->adapter();
$adapter->write('source.txt', 'contents to be moved', new Config(['ContentType' => 'text/plain']));
$mimeTypeSource = $adapter->mimeType('source.txt')->mimeType();
$this->assertSame('text/plain', $mimeTypeSource);
$adapter->move('source.txt', 'destination.txt', new Config(
['ContentType' => 'text/plain+special']
));
$mimeTypeDestination = $adapter->mimeType('destination.txt')->mimeType();
$this->assertSame('text/plain', $mimeTypeDestination);
}
/**
* @test
*/
public function copying_with_updated_metadata(): void
{
$adapter = $this->adapter();
$adapter->write('source.txt', 'contents to be moved', new Config(['ContentType' => 'text/plain']));
$mimeTypeSource = $adapter->mimeType('source.txt')->mimeType();
$this->assertSame('text/plain', $mimeTypeSource);
$adapter->copy('source.txt', 'destination.txt', new Config(
['ContentType' => 'text/plain+special', 'MetadataDirective' => 'REPLACE']
));
$mimeTypeDestination = $adapter->mimeType('destination.txt')->mimeType();
$this->assertSame('text/plain+special', $mimeTypeDestination);
}
/**
* @test
*/
public function setting_acl_via_options(): void
{
$adapter = $this->adapter();
$prefixer = new PathPrefixer(static::$adapterPrefix);
$prefixedPath = $prefixer->prefixPath('path.txt');
$adapter->write('path.txt', 'contents', new Config(['ACL' => 'bucket-owner-full-control']));
$arguments = ['Bucket' => getenv('FLYSYSTEM_AWS_S3_BUCKET'), 'Key' => $prefixedPath];
$command = static::$s3Client->getCommand('GetObjectAcl', $arguments);
$response = static::$s3Client->execute($command)->toArray();
$permission = $response['Grants'][0]['Permission'];
self::assertEquals('FULL_CONTROL', $permission);
}
/**
* @test
*/
public function moving_a_file_with_visibility(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->move('source.txt', 'destination.txt', new Config([Config::OPTION_VISIBILITY => Visibility::PRIVATE]));
$this->assertFalse(
$adapter->fileExists('source.txt'),
'After moving a file should no longer exist in the original location.'
);
$this->assertTrue(
$adapter->fileExists('destination.txt'),
'After moving, a file should be present at the new location.'
);
$this->assertEquals(Visibility::PRIVATE, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
/**
* @test
*/
public function specifying_a_custom_checksum_algo_is_not_supported(): void
{
/** @var AwsS3V3Adapter $adapter */
$adapter = $this->adapter();
$this->expectException(ChecksumAlgoIsNotSupported::class);
$adapter->checksum('something', new Config(['checksum_algo' => 'md5']));
}
/**
* @test
*/
public function copying_a_file_with_visibility(): void
{
$this->runScenario(function () {
$adapter = $this->adapter();
$adapter->write(
'source.txt',
'contents to be copied',
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
);
$adapter->copy('source.txt', 'destination.txt', new Config([Config::OPTION_VISIBILITY => Visibility::PRIVATE]));
$this->assertTrue($adapter->fileExists('source.txt'));
$this->assertTrue($adapter->fileExists('destination.txt'));
$this->assertEquals(Visibility::PRIVATE, $adapter->visibility('destination.txt')->visibility());
$this->assertEquals('contents to be copied', $adapter->read('destination.txt'));
});
}
protected static function createFilesystemAdapter(bool $streaming = true, array $options = []): FilesystemAdapter
{
static::$stubS3Client = new S3ClientStub(static::s3Client());
/** @var string $bucket */
$bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET');
$prefix = static::$adapterPrefix;
return new AwsS3V3Adapter(static::$stubS3Client, $bucket, $prefix, null, null, $options, $streaming);
}
}
================================================
FILE: src/AwsS3V3/LICENSE
================================================
Copyright (c) 2013-2026 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.
================================================
FILE: src/AwsS3V3/PortableVisibilityConverter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AwsS3V3;
use League\Flysystem\Visibility;
class PortableVisibilityConverter implements VisibilityConverter
{
private const PUBLIC_GRANTEE_URI = 'http://acs.amazonaws.com/groups/global/AllUsers';
private const PUBLIC_GRANTS_PERMISSION = 'READ';
private const PUBLIC_ACL = 'public-read';
private const PRIVATE_ACL = 'private';
public function __construct(private string $defaultForDirectories = Visibility::PUBLIC)
{
}
public function visibilityToAcl(string $visibility): string
{
if ($visibility === Visibility::PUBLIC) {
return self::PUBLIC_ACL;
}
return self::PRIVATE_ACL;
}
public function aclToVisibility(array $grants): string
{
foreach ($grants as $grant) {
$granteeUri = $grant['Grantee']['URI'] ?? null;
$permission = $grant['Permission'] ?? null;
if ($granteeUri === self::PUBLIC_GRANTEE_URI && $permission === self::PUBLIC_GRANTS_PERMISSION) {
return Visibility::PUBLIC;
}
}
return Visibility::PRIVATE;
}
public function defaultForDirectories(): string
{
return $this->defaultForDirectories;
}
}
================================================
FILE: src/AwsS3V3/README.md
================================================
## Sub-split of Flysystem for AWS S3.
> ⚠️ this is a sub-split, for pull requests and issues, visit: https://github.com/thephpleague/flysystem
```bash
composer require league/flysystem-aws-s3-v3
```
View the [documentation](https://flysystem.thephpleague.com/docs/adapter/aws-s3-v3/).
================================================
FILE: src/AwsS3V3/S3ClientStub.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AwsS3V3;
use Aws\Command;
use Aws\CommandInterface;
use Aws\ResultInterface;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3ClientInterface;
use Aws\S3\S3ClientTrait;
use GuzzleHttp\Psr7\Response;
use Throwable;
use function GuzzleHttp\Promise\promise_for;
/**
* @codeCoverageIgnore
*/
class S3ClientStub implements S3ClientInterface
{
use S3ClientTrait;
/**
* @var S3ClientInterface
*/
private $actualClient;
/**
* @var S3Exception[]
*/
private $stagedExceptions = [];
/**
* @var ResultInterface[]
*/
private $stagedResult = [];
/**
* @var Throwable|null
*/
private $exceptionForUpload = null;
public function __construct(S3ClientInterface $client)
{
return $this->actualClient = $client;
}
public function throwDuringUpload(Throwable $throwable): void
{
$this->exceptionForUpload = $throwable;
}
public function upload($bucket, $key, $body, $acl = 'private', array $options = [])
{
if ($this->exceptionForUpload instanceof Throwable) {
$throwable = $this->exceptionForUpload;
$this->exceptionForUpload = null;
throw $throwable;
}
return $this->actualClient->upload($bucket, $key, $body, $acl, $options);
}
public function failOnNextCopy(): void
{
$this->throwExceptionWhenExecutingCommand('CopyObject');
}
public function throwExceptionWhenExecutingCommand(string $commandName, ?S3Exception $exception = null): void
{
$this->stagedExceptions[$commandName] = $exception ?? new S3Exception($commandName, new Command($commandName));
}
public function throw500ExceptionWhenExecutingCommand(string $commandName): void
{
$response = new Response(500);
$exception = new S3Exception($commandName, new Command($commandName), compact('response'));
$this->throwExceptionWhenExecutingCommand($commandName, $exception);
}
public function stageResultForCommand(string $commandName, ResultInterface $result): void
{
$this->stagedResult[$commandName] = $result;
}
public function execute(CommandInterface $command)
{
return $this->executeAsync($command)->wait();
}
public function getCommand($name, array $args = [])
{
return $this->actualClient->getCommand($name, $args);
}
public function getHandlerList()
{
return $this->actualClient->getHandlerList();
}
public function getIterator($name, array $args = [])
{
return $this->actualClient->getIterator($name, $args);
}
public function __call($name, array $arguments)
{
return $this->actualClient->__call($name, $arguments);
}
public function executeAsync(CommandInterface $command)
{
$name = $command->getName();
if (array_key_exists($name, $this->stagedExceptions)) {
$exception = $this->stagedExceptions[$name];
unset($this->stagedExceptions[$name]);
throw $exception;
}
if (array_key_exists($name, $this->stagedResult)) {
$result = $this->stagedResult[$name];
unset($this->stagedResult[$name]);
return promise_for($result);
}
return $this->actualClient->executeAsync($command);
}
public function getCredentials()
{
return $this->actualClient->getCredentials();
}
public function getRegion()
{
return $this->actualClient->getRegion();
}
public function getEndpoint()
{
return $this->actualClient->getEndpoint();
}
public function getApi()
{
return $this->actualClient->getApi();
}
public function getConfig($option = null)
{
return $this->actualClient->getConfig($option);
}
public function getPaginator($name, array $args = [])
{
return $this->actualClient->getPaginator($name, $args);
}
public function waitUntil($name, array $args = [])
{
$this->actualClient->waitUntil($name, $args);
}
public function getWaiter($name, array $args = [])
{
return $this->actualClient->getWaiter($name, $args);
}
public function createPresignedRequest(CommandInterface $command, $expires, array $options = [])
{
return $this->actualClient->createPresignedRequest($command, $expires, $options);
}
public function getObjectUrl($bucket, $key)
{
return $this->actualClient->getObjectUrl($bucket, $key);
}
}
================================================
FILE: src/AwsS3V3/VisibilityConverter.php
================================================
<?php
declare(strict_types=1);
namespace League\Flysystem\AwsS3V3;
interface VisibilityConverter
{
public function visibilityToAcl(string $visib
gitextract_99z1k6qe/
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── Bug.md
│ │ ├── Feature_Request.md
│ │ └── Question.md
│ ├── release.yml
│ ├── stale.yml
│ └── workflows/
│ ├── publish-subsplits.yml
│ ├── quality-assurance.yml
│ └── set-subsplit-default-branch.yml
├── .gitignore
├── .php-cs-fixer.dist.php
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── INFO.md
├── LICENSE
├── bin/
│ ├── .gitignore
│ ├── check-versions.php
│ ├── close-subsplit-prs.yml
│ ├── set-flysystem-version.php
│ ├── tools.php
│ └── update-subsplit-closers.php
├── composer.json
├── config.subsplit-publish.json
├── docker-compose.yml
├── mocked-functions.php
├── phpstan-baseline.neon
├── phpstan.neon
├── phpunit.php
├── phpunit.xml.dist
├── readme.md
├── src/
│ ├── AdapterTestUtilities/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ExceptionThrowingFilesystemAdapter.php
│ │ ├── FilesystemAdapterTestCase.php
│ │ ├── README.md
│ │ ├── RetryOnTestException.php
│ │ ├── ToxiproxyManagement.php
│ │ ├── composer.json
│ │ ├── test-functions.php
│ │ └── test_files/
│ │ └── unknown-mime-type.md5
│ ├── AsyncAwsS3/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── AsyncAwsS3Adapter.php
│ │ ├── AsyncAwsS3AdapterTest.php
│ │ ├── LICENSE
│ │ ├── PortableVisibilityConverter.php
│ │ ├── README.md
│ │ ├── S3ClientStub.php
│ │ ├── VisibilityConverter.php
│ │ └── composer.json
│ ├── AwsS3V3/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── AwsS3V3Adapter.php
│ │ ├── AwsS3V3AdapterTest.php
│ │ ├── LICENSE
│ │ ├── PortableVisibilityConverter.php
│ │ ├── README.md
│ │ ├── S3ClientStub.php
│ │ ├── VisibilityConverter.php
│ │ └── composer.json
│ ├── AzureBlobStorage/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── AzureBlobStorageAdapter.php
│ │ ├── AzureBlobStorageAdapterTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── composer.json
│ ├── CalculateChecksumFromStream.php
│ ├── ChecksumAlgoIsNotSupported.php
│ ├── ChecksumProvider.php
│ ├── Config.php
│ ├── ConfigTest.php
│ ├── CorruptedPathDetected.php
│ ├── DecoratedAdapter.php
│ ├── DirectoryAttributes.php
│ ├── DirectoryAttributesTest.php
│ ├── DirectoryListing.php
│ ├── DirectoryListingTest.php
│ ├── ExceptionInformationTest.php
│ ├── FileAttributes.php
│ ├── FileAttributesTest.php
│ ├── Filesystem.php
│ ├── FilesystemAdapter.php
│ ├── FilesystemException.php
│ ├── FilesystemOperationFailed.php
│ ├── FilesystemOperator.php
│ ├── FilesystemReader.php
│ ├── FilesystemTest.php
│ ├── FilesystemWriter.php
│ ├── Ftp/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ConnectionProvider.php
│ │ ├── ConnectivityChecker.php
│ │ ├── ConnectivityCheckerThatCanFail.php
│ │ ├── FtpAdapter.php
│ │ ├── FtpAdapterTest.php
│ │ ├── FtpAdapterTestCase.php
│ │ ├── FtpConnectionException.php
│ │ ├── FtpConnectionOptions.php
│ │ ├── FtpConnectionProvider.php
│ │ ├── FtpConnectionProviderTest.php
│ │ ├── FtpdAdapterTest.php
│ │ ├── InvalidListResponseReceived.php
│ │ ├── LICENSE
│ │ ├── NoopCommandConnectivityChecker.php
│ │ ├── NoopCommandConnectivityCheckerTest.php
│ │ ├── README.md
│ │ ├── RawListFtpConnectivityChecker.php
│ │ ├── RawListFtpConnectivityCheckerTest.php
│ │ ├── StubConnectionProvider.php
│ │ ├── UnableToAuthenticate.php
│ │ ├── UnableToConnectToFtpHost.php
│ │ ├── UnableToEnableUtf8Mode.php
│ │ ├── UnableToMakeConnectionPassive.php
│ │ ├── UnableToResolveConnectionRoot.php
│ │ ├── UnableToSetFtpOption.php
│ │ └── composer.json
│ ├── GoogleCloudStorage/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── GoogleCloudStorageAdapter.php
│ │ ├── GoogleCloudStorageAdapterTest.php
│ │ ├── GoogleCloudStorageAdapterWithoutAclTest.php
│ │ ├── LICENSE
│ │ ├── PortableVisibilityHandler.php
│ │ ├── README.md
│ │ ├── StubRiggedBucket.php
│ │ ├── StubStorageClient.php
│ │ ├── UniformBucketLevelAccessVisibility.php
│ │ ├── VisibilityHandler.php
│ │ └── composer.json
│ ├── GridFS/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── GridFSAdapter.php
│ │ ├── GridFSAdapterTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── composer.json
│ ├── InMemory/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── InMemoryFile.php
│ │ ├── InMemoryFilesystemAdapter.php
│ │ ├── InMemoryFilesystemAdapterTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── StaticInMemoryAdapterRegistry.php
│ │ ├── StaticInMemoryAdapterRegistryTest.php
│ │ └── composer.json
│ ├── InvalidStreamProvided.php
│ ├── InvalidVisibilityProvided.php
│ ├── Local/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── FallbackMimeTypeDetector.php
│ │ ├── LICENSE
│ │ ├── LocalFilesystemAdapter.php
│ │ ├── LocalFilesystemAdapterTest.php
│ │ ├── README.md
│ │ └── composer.json
│ ├── MountManager.php
│ ├── MountManagerTest.php
│ ├── PathNormalizer.php
│ ├── PathPrefixer.php
│ ├── PathPrefixerTest.php
│ ├── PathPrefixing/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── LICENSE
│ │ ├── PathPrefixedAdapter.php
│ │ ├── PathPrefixedAdapterTest.php
│ │ ├── README.md
│ │ └── composer.json
│ ├── PathTraversalDetected.php
│ ├── PhpseclibV2/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ConnectionProvider.php
│ │ ├── ConnectivityChecker.php
│ │ ├── FixatedConnectivityChecker.php
│ │ ├── README.md
│ │ ├── SftpAdapter.php
│ │ ├── SftpAdapterTest.php
│ │ ├── SftpConnectionProvider.php
│ │ ├── SftpConnectionProviderTest.php
│ │ ├── SftpStub.php
│ │ ├── SimpleConnectivityChecker.php
│ │ ├── StubSftpConnectionProvider.php
│ │ ├── UnableToAuthenticate.php
│ │ ├── UnableToConnectToSftpHost.php
│ │ ├── UnableToEstablishAuthenticityOfHost.php
│ │ ├── UnableToLoadPrivateKey.php
│ │ └── composer.json
│ ├── PhpseclibV3/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ConnectionProvider.php
│ │ ├── ConnectivityChecker.php
│ │ ├── FixatedConnectivityChecker.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── SftpAdapter.php
│ │ ├── SftpAdapterTest.php
│ │ ├── SftpConnectionProvider.php
│ │ ├── SftpConnectionProviderTest.php
│ │ ├── SftpStub.php
│ │ ├── SimpleConnectivityChecker.php
│ │ ├── StubSftpConnectionProvider.php
│ │ ├── UnableToAuthenticate.php
│ │ ├── UnableToConnectToSftpHost.php
│ │ ├── UnableToEstablishAuthenticityOfHost.php
│ │ ├── UnableToLoadPrivateKey.php
│ │ └── composer.json
│ ├── PortableVisibilityGuard.php
│ ├── ProxyArrayAccessToProperties.php
│ ├── ReadOnly/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── ReadOnlyFilesystemAdapter.php
│ │ ├── ReadOnlyFilesystemAdapterTest.php
│ │ └── composer.json
│ ├── ResolveIdenticalPathConflict.php
│ ├── StorageAttributes.php
│ ├── SymbolicLinkEncountered.php
│ ├── UnableToCheckDirectoryExistence.php
│ ├── UnableToCheckExistence.php
│ ├── UnableToCheckFileExistence.php
│ ├── UnableToCopyFile.php
│ ├── UnableToCreateDirectory.php
│ ├── UnableToDeleteDirectory.php
│ ├── UnableToDeleteFile.php
│ ├── UnableToGeneratePublicUrl.php
│ ├── UnableToGenerateTemporaryUrl.php
│ ├── UnableToListContents.php
│ ├── UnableToMountFilesystem.php
│ ├── UnableToMoveFile.php
│ ├── UnableToProvideChecksum.php
│ ├── UnableToReadFile.php
│ ├── UnableToResolveFilesystemMount.php
│ ├── UnableToRetrieveMetadata.php
│ ├── UnableToSetVisibility.php
│ ├── UnableToWriteFile.php
│ ├── UnixVisibility/
│ │ ├── PortableVisibilityConverter.php
│ │ ├── PortableVisibilityConverterTest.php
│ │ └── VisibilityConverter.php
│ ├── UnreadableFileEncountered.php
│ ├── UrlGeneration/
│ │ ├── ChainedPublicUrlGenerator.php
│ │ ├── ChainedPublicUrlGeneratorTest.php
│ │ ├── PrefixPublicUrlGenerator.php
│ │ ├── PublicUrlGenerator.php
│ │ ├── ShardedPrefixPublicUrlGenerator.php
│ │ └── TemporaryUrlGenerator.php
│ ├── Visibility.php
│ ├── WebDAV/
│ │ ├── .gitattributes
│ │ ├── .github/
│ │ │ └── workflows/
│ │ │ └── close-subsplit-prs.yaml
│ │ ├── ByteMarkWebDAVServerTest.php
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── SabreServerTest.php
│ │ ├── UrlPrefixingClientStub.php
│ │ ├── WebDAVAdapter.php
│ │ ├── WebDAVAdapterTestCase.php
│ │ ├── composer.json
│ │ └── resources/
│ │ ├── .gitignore
│ │ └── server.php
│ ├── WhitespacePathNormalizer.php
│ ├── WhitespacePathNormalizerTest.php
│ └── ZipArchive/
│ ├── .gitattributes
│ ├── .github/
│ │ └── workflows/
│ │ └── close-subsplit-prs.yaml
│ ├── FilesystemZipArchiveProvider.php
│ ├── LICENSE
│ ├── NoRootPrefixZipArchiveAdapterTest.php
│ ├── PrefixedRootZipArchiveAdapterTest.php
│ ├── README.md
│ ├── StubZipArchive.php
│ ├── StubZipArchiveProvider.php
│ ├── UnableToCreateParentDirectory.php
│ ├── UnableToOpenZipArchive.php
│ ├── ZipArchiveAdapter.php
│ ├── ZipArchiveAdapterTestCase.php
│ ├── ZipArchiveException.php
│ ├── ZipArchiveProvider.php
│ └── composer.json
└── test_files/
├── .gitignore
├── sftp/
│ ├── id_rsa
│ ├── id_rsa.pub
│ ├── ssh_host_ed25519_key
│ ├── ssh_host_ed25519_key.pub
│ ├── ssh_host_rsa_key
│ ├── ssh_host_rsa_key.pub
│ ├── sshd_custom_configs.sh
│ ├── unknown.key
│ └── users.conf
├── toxiproxy/
│ └── toxiproxy.json
├── wait_for_ftp.php
└── wait_for_sftp.php
SYMBOL INDEX (1627 symbols across 175 files)
FILE: bin/check-versions.php
function constraint_has_conflict (line 26) | function constraint_has_conflict(string $mainConstraint, string $package...
FILE: bin/tools.php
function write_line (line 5) | function write_line(string $line)
function panic (line 10) | function panic(string $reason)
FILE: mocked-functions.php
function rmdir (line 4) | function rmdir(...$arguments)
function unlink (line 13) | function unlink(...$arguments)
function filemtime (line 22) | function filemtime(...$arguments)
function filesize (line 31) | function filesize(...$arguments)
function time (line 42) | function time()
function ftp_raw (line 53) | function ftp_raw(...$arguments)
function ftp_set_option (line 62) | function ftp_set_option(...$arguments)
function ftp_pasv (line 71) | function ftp_pasv(...$arguments)
function ftp_pwd (line 80) | function ftp_pwd(...$arguments)
function ftp_fput (line 89) | function ftp_fput(...$arguments)
function ftp_chmod (line 98) | function ftp_chmod(...$arguments)
function ftp_mkdir (line 107) | function ftp_mkdir(...$arguments)
function ftp_delete (line 116) | function ftp_delete(...$arguments)
function ftp_rmdir (line 125) | function ftp_rmdir(...$arguments)
function ftp_fget (line 134) | function ftp_fget(...$arguments)
function ftp_rawlist (line 143) | function ftp_rawlist(...$arguments)
function stream_get_contents (line 154) | function stream_get_contents(...$arguments)
FILE: src/AdapterTestUtilities/ExceptionThrowingFilesystemAdapter.php
class ExceptionThrowingFilesystemAdapter (line 12) | class ExceptionThrowingFilesystemAdapter implements FilesystemAdapter
method __construct (line 24) | public function __construct(FilesystemAdapter $adapter)
method stageException (line 29) | public function stageException(string $method, string $path, Filesyste...
method throwStagedException (line 34) | private function throwStagedException(string $method, $path): void
method fileExists (line 48) | public function fileExists(string $path): bool
method write (line 55) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 62) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 69) | public function read(string $path): string
method readStream (line 76) | public function readStream(string $path)
method delete (line 83) | public function delete(string $path): void
method deleteDirectory (line 90) | public function deleteDirectory(string $path): void
method createDirectory (line 97) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 104) | public function setVisibility(string $path, string $visibility): void
method visibility (line 111) | public function visibility(string $path): FileAttributes
method mimeType (line 118) | public function mimeType(string $path): FileAttributes
method lastModified (line 125) | public function lastModified(string $path): FileAttributes
method fileSize (line 132) | public function fileSize(string $path): FileAttributes
method listContents (line 139) | public function listContents(string $path, bool $deep): iterable
method move (line 146) | public function move(string $source, string $destination, Config $conf...
method copy (line 153) | public function copy(string $source, string $destination, Config $conf...
method directoryExists (line 160) | public function directoryExists(string $path): bool
FILE: src/AdapterTestUtilities/FilesystemAdapterTestCase.php
class FilesystemAdapterTestCase (line 35) | abstract class FilesystemAdapterTestCase extends TestCase
method clearFilesystemAdapterCache (line 49) | public static function clearFilesystemAdapterCache(): void
method createFilesystemAdapter (line 54) | abstract protected static function createFilesystemAdapter(): Filesyst...
method adapter (line 56) | public function adapter(): FilesystemAdapter
method tearDownAfterClass (line 65) | public static function tearDownAfterClass(): void
method setUp (line 70) | protected function setUp(): void
method useAdapter (line 76) | protected function useAdapter(FilesystemAdapter $adapter): FilesystemA...
method cleanupAdapter (line 87) | public function cleanupAdapter(): void
method clearStorage (line 93) | public function clearStorage(): void
method clearCustomAdapter (line 121) | public function clearCustomAdapter(): void
method writing_and_reading_with_string (line 132) | public function writing_and_reading_with_string(): void
method writing_a_file_with_a_stream (line 149) | public function writing_a_file_with_a_stream(): void
method writing_and_reading_files_with_special_path (line 174) | public function writing_and_reading_files_with_special_path(string $pa...
method filenameProvider (line 186) | public static function filenameProvider(): Generator
method writing_a_file_with_an_empty_stream (line 207) | public function writing_a_file_with_an_empty_stream(): void
method listing_a_directory_named_0 (line 231) | public function listing_a_directory_named_0(): void
method reading_a_file (line 246) | public function reading_a_file(): void
method reading_a_file_with_a_stream (line 260) | public function reading_a_file_with_a_stream(): void
method overwriting_a_file (line 277) | public function overwriting_a_file(): void
method a_file_exists_only_when_it_is_written_and_not_deleted (line 295) | public function a_file_exists_only_when_it_is_written_and_not_deleted(...
method listing_contents_shallow (line 316) | public function listing_contents_shallow(): void
method checking_if_a_non_existing_directory_exists (line 344) | public function checking_if_a_non_existing_directory_exists(): void
method checking_if_a_directory_exists_after_writing_a_file (line 355) | public function checking_if_a_directory_exists_after_writing_a_file():...
method checking_if_a_directory_exists_after_creating_it (line 367) | public function checking_if_a_directory_exists_after_creating_it(): void
method listing_contents_recursive (line 383) | public function listing_contents_recursive(): void
method formatIncorrectListingCount (line 397) | protected function formatIncorrectListingCount(array $items): string
method givenWeHaveAnExistingFile (line 409) | protected function givenWeHaveAnExistingFile(string $path, string $con...
method fetching_file_size (line 419) | public function fetching_file_size(): void
method setting_visibility (line 434) | public function setting_visibility(): void
method fetching_file_size_of_a_directory (line 455) | public function fetching_file_size_of_a_directory(): void
method fetching_file_size_of_non_existing_file (line 470) | public function fetching_file_size_of_non_existing_file(): void
method fetching_last_modified_of_non_existing_file (line 482) | public function fetching_last_modified_of_non_existing_file(): void
method fetching_visibility_of_non_existing_file (line 494) | public function fetching_visibility_of_non_existing_file(): void
method fetching_the_mime_type_of_an_svg_file (line 506) | public function fetching_the_mime_type_of_an_svg_file(): void
method fetching_mime_type_of_non_existing_file (line 520) | public function fetching_mime_type_of_non_existing_file(): void
method fetching_unknown_mime_type_of_a_file (line 532) | public function fetching_unknown_mime_type_of_a_file(): void
method listing_a_toplevel_directory (line 549) | public function listing_a_toplevel_directory(): void
method writing_and_reading_with_streams (line 564) | public function writing_and_reading_with_streams(): void
method setting_visibility_on_a_file_that_does_not_exist (line 586) | public function setting_visibility_on_a_file_that_does_not_exist(): void
method copying_a_file (line 598) | public function copying_a_file(): void
method copying_a_file_that_does_not_exist (line 621) | public function copying_a_file_that_does_not_exist(): void
method copying_a_file_again (line 633) | public function copying_a_file_again(): void
method moving_a_file (line 655) | public function moving_a_file(): void
method file_exists_on_directory_is_false (line 682) | public function file_exists_on_directory_is_false(): void
method directory_exists_on_file_is_false (line 698) | public function directory_exists_on_file_is_false(): void
method reading_a_file_that_does_not_exist (line 714) | public function reading_a_file_that_does_not_exist(): void
method moving_a_file_that_does_not_exist (line 726) | public function moving_a_file_that_does_not_exist(): void
method trying_to_delete_a_non_existing_file (line 738) | public function trying_to_delete_a_non_existing_file(): void
method checking_if_files_exist (line 751) | public function checking_if_files_exist(): void
method fetching_last_modified (line 767) | public function fetching_last_modified(): void
method failing_to_read_a_non_existing_file_into_a_stream (line 785) | public function failing_to_read_a_non_existing_file_into_a_stream(): void
method failing_to_read_a_non_existing_file (line 795) | public function failing_to_read_a_non_existing_file(): void
method creating_a_directory (line 805) | public function creating_a_directory(): void
method copying_a_file_with_collision (line 828) | public function copying_a_file_with_collision(): void
method moving_a_file_with_collision (line 845) | public function moving_a_file_with_collision(): void
method copying_a_file_with_same_destination (line 865) | public function copying_a_file_with_same_destination(): void
method moving_a_file_with_same_destination (line 881) | public function moving_a_file_with_same_destination(): void
method assertFileExistsAtPath (line 894) | protected function assertFileExistsAtPath(string $path): void
method generating_a_public_url (line 905) | public function generating_a_public_url(): void
method generating_a_temporary_url (line 924) | public function generating_a_temporary_url(): void
method get_checksum (line 944) | public function get_checksum(): void
method cannot_get_checksum_for_non_existent_file (line 960) | public function cannot_get_checksum_for_non_existent_file(): void
method cannot_get_checksum_for_directory (line 976) | public function cannot_get_checksum_for_directory(): void
FILE: src/AdapterTestUtilities/RetryOnTestException.php
type RetryOnTestException (line 15) | trait RetryOnTestException
method retryOnException (line 27) | protected function retryOnException(string $className, int $timout = 2...
method retryScenarioOnException (line 33) | protected function retryScenarioOnException(string $className, callabl...
method dontRetryOnException (line 39) | protected function dontRetryOnException(): void
method runSetup (line 49) | protected function runSetup(callable $scenario): void
method runScenario (line 63) | protected function runScenario(callable $scenario): void
FILE: src/AdapterTestUtilities/ToxiproxyManagement.php
class ToxiproxyManagement (line 20) | final class ToxiproxyManagement
method __construct (line 25) | public function __construct(Client $apiClient)
method forServer (line 30) | public static function forServer(string $apiUri = 'http://localhost:84...
method removeAllToxics (line 42) | public function removeAllToxics(): void
method resetPeerOnRequest (line 52) | public function resetPeerOnRequest(
method addToxic (line 71) | private function addToxic(string $proxyName, array $configuration): void
FILE: src/AdapterTestUtilities/test-functions.php
function return_mocked_value (line 5) | function return_mocked_value(string $name)
function reset_function_mocks (line 10) | function reset_function_mocks()
function mock_function (line 19) | function mock_function(string $name, ...$returns)
function is_mocked (line 25) | function is_mocked(string $name)
function stream_with_contents (line 30) | function stream_with_contents(string $contents)
function delete_directory (line 39) | function delete_directory(string $dir): void
FILE: src/AsyncAwsS3/AsyncAwsS3Adapter.php
class AsyncAwsS3Adapter (line 50) | class AsyncAwsS3Adapter implements FilesystemAdapter, PublicUrlGenerator...
method __construct (line 112) | public function __construct(
method fileExists (line 128) | public function fileExists(string $path): bool
method write (line 142) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 147) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 152) | public function read(string $path): string
method readStream (line 159) | public function readStream(string $path)
method delete (line 166) | public function delete(string $path): void
method deleteDirectory (line 177) | public function deleteDirectory(string $path): void
method createDirectory (line 210) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 222) | public function setVisibility(string $path, string $visibility): void
method visibility (line 237) | public function visibility(string $path): FileAttributes
method mimeType (line 253) | public function mimeType(string $path): FileAttributes
method lastModified (line 264) | public function lastModified(string $path): FileAttributes
method fileSize (line 275) | public function fileSize(string $path): FileAttributes
method directoryExists (line 286) | public function directoryExists(string $path): bool
method listContents (line 298) | public function listContents(string $path, bool $deep): iterable
method move (line 326) | public function move(string $source, string $destination, Config $conf...
method copy (line 340) | public function copy(string $source, string $destination, Config $conf...
method upload (line 373) | private function upload(string $path, $body, Config $config): void
method determineAcl (line 401) | private function determineAcl(Config $config): string
method createOptionsFromConfig (line 408) | private function createOptionsFromConfig(Config $config): array
method fetchFileMetadata (line 423) | private function fetchFileMetadata(string $path, string $type): FileAt...
method mapS3ObjectMetadata (line 446) | private function mapS3ObjectMetadata($item, ?string $path = null): Sto...
method extractExtraMetadata (line 492) | private function extractExtraMetadata($metadata): array
method retrievePaginatedListing (line 510) | private function retrievePaginatedListing(array $options): Generator
method readObject (line 519) | private function readObject(string $path): ResultStream
method createObjectIdentifierForXmlRequest (line 530) | private function createObjectIdentifierForXmlRequest(string $key): Obj...
method publicUrl (line 541) | public function publicUrl(string $path, Config $config): string
method checksum (line 554) | public function checksum(string $path, Config $config): string
method temporaryUrl (line 575) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/AsyncAwsS3/AsyncAwsS3AdapterTest.php
class AsyncAwsS3AdapterTest (line 39) | class AsyncAwsS3AdapterTest extends FilesystemAdapterTestCase
method awsConfig (line 61) | private static function awsConfig(): array
method setUp (line 78) | protected function setUp(): void
method setUpBeforeClass (line 84) | public static function setUpBeforeClass(): void
method tearDown (line 89) | protected function tearDown(): void
method s3Client (line 109) | private static function s3Client(): S3Client
method specifying_a_custom_checksum_algo_is_not_supported (line 129) | public function specifying_a_custom_checksum_algo_is_not_supported(): ...
method issue_287 (line 144) | public function issue_287(): void
method writing_with_a_specific_mime_type (line 155) | public function writing_with_a_specific_mime_type(): void
method listing_contents_recursive (line 166) | public function listing_contents_recursive(): void
method failing_to_delete_while_moving (line 187) | public function failing_to_delete_while_moving(): void
method failing_to_delete_a_file (line 201) | public function failing_to_delete_a_file(): void
method delete_directory_replaces_special_characters_by_xml_entity_codes (line 214) | public function delete_directory_replaces_special_characters_by_xml_en...
method delete_directory_throws_exception_if_object_key_can_not_be_escaped_correctly (line 237) | public function delete_directory_throws_exception_if_object_key_can_no...
method fetching_unknown_mime_type_of_a_file (line 268) | public function fetching_unknown_mime_type_of_a_file(): void
method failing_to_retrieve_metadata (line 282) | public function failing_to_retrieve_metadata(Exception $exception, str...
method dpFailingMetadataGetters (line 293) | public static function dpFailingMetadataGetters(): iterable
method failing_to_check_for_file_existence (line 303) | public function failing_to_check_for_file_existence(): void
method configuring_http_streaming_via_options (line 317) | public function configuring_http_streaming_via_options(): void
method write_with_s3_client (line 332) | public function write_with_s3_client(): void
method write_with_simple_s3_client (line 366) | public function write_with_simple_s3_client(): void
method failing_to_write_a_file (line 389) | public function failing_to_write_a_file(): void
method moving_a_file_with_visibility (line 401) | public function moving_a_file_with_visibility(): void
method copying_a_file_with_visibility (line 427) | public function copying_a_file_with_visibility(): void
method copying_a_file_with_non_ascii_characters (line 449) | public function copying_a_file_with_non_ascii_characters(): void
method top_level_directory_excluded_from_listing (line 470) | public function top_level_directory_excluded_from_listing(): void
method failing_to_list_contents (line 490) | public function failing_to_list_contents(): void
method createFilesystemAdapter (line 500) | protected static function createFilesystemAdapter(): FilesystemAdapter
FILE: src/AsyncAwsS3/PortableVisibilityConverter.php
class PortableVisibilityConverter (line 10) | class PortableVisibilityConverter implements VisibilityConverter
method __construct (line 22) | public function __construct(string $defaultForDirectories = Visibility...
method visibilityToAcl (line 27) | public function visibilityToAcl(string $visibility): string
method aclToVisibility (line 39) | public function aclToVisibility(array $grants): string
method defaultForDirectories (line 56) | public function defaultForDirectories(): string
FILE: src/AsyncAwsS3/S3ClientStub.php
class S3ClientStub (line 37) | class S3ClientStub extends SimpleS3Client
method __construct (line 54) | public function __construct(SimpleS3Client $client, $configuration = [])
method throwExceptionWhenExecutingCommand (line 60) | public function throwExceptionWhenExecutingCommand(string $commandName...
method stageResultForCommand (line 65) | public function stageResultForCommand(string $commandName, Result $res...
method getStagedResult (line 70) | private function getStagedResult(string $name): ?Result
method copyObject (line 92) | public function copyObject($input): CopyObjectOutput
method deleteObject (line 101) | public function deleteObject($input): DeleteObjectOutput
method headObject (line 110) | public function headObject($input): HeadObjectOutput
method objectExists (line 119) | public function objectExists($input): ObjectExistsWaiter
method listObjectsV2 (line 128) | public function listObjectsV2($input): ListObjectsV2Output
method deleteObjects (line 137) | public function deleteObjects($input): DeleteObjectsOutput
method getObjectAcl (line 146) | public function getObjectAcl($input): GetObjectAclOutput
method putObjectAcl (line 155) | public function putObjectAcl($input): PutObjectAclOutput
method putObject (line 164) | public function putObject($input): PutObjectOutput
method getObject (line 173) | public function getObject($input): GetObjectOutput
method getUrl (line 179) | public function getUrl(string $bucket, string $key): string
method getPresignedUrl (line 184) | public function getPresignedUrl(string $bucket, string $key, ?DateTime...
FILE: src/AsyncAwsS3/VisibilityConverter.php
type VisibilityConverter (line 9) | interface VisibilityConverter
method visibilityToAcl (line 11) | public function visibilityToAcl(string $visibility): string;
method aclToVisibility (line 16) | public function aclToVisibility(array $grants): string;
method defaultForDirectories (line 18) | public function defaultForDirectories(): string;
FILE: src/AwsS3V3/AwsS3V3Adapter.php
class AwsS3V3Adapter (line 42) | class AwsS3V3Adapter implements FilesystemAdapter, PublicUrlGenerator, C...
method __construct (line 101) | public function __construct(
method fileExists (line 118) | public function fileExists(string $path): bool
method directoryExists (line 127) | public function directoryExists(string $path): bool
method write (line 141) | public function write(string $path, string $contents, Config $config):...
method upload (line 151) | private function upload(string $path, $body, Config $config): void
method determineAcl (line 169) | private function determineAcl(Config $config): string
method createOptionsFromConfig (line 176) | private function createOptionsFromConfig(Config $config): array
method writeStream (line 204) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 209) | public function read(string $path): string
method readStream (line 216) | public function readStream(string $path)
method delete (line 224) | public function delete(string $path): void
method deleteDirectory (line 236) | public function deleteDirectory(string $path): void
method createDirectory (line 248) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 255) | public function setVisibility(string $path, string $visibility): void
method visibility (line 271) | public function visibility(string $path): FileAttributes
method fetchFileMetadata (line 287) | private function fetchFileMetadata(string $path, string $type): FileAt...
method mapS3ObjectMetadata (line 307) | private function mapS3ObjectMetadata(array $metadata, string $path): S...
method extractExtraMetadata (line 329) | private function extractExtraMetadata(array $metadata): array
method mimeType (line 342) | public function mimeType(string $path): FileAttributes
method lastModified (line 353) | public function lastModified(string $path): FileAttributes
method fileSize (line 364) | public function fileSize(string $path): FileAttributes
method listContents (line 375) | public function listContents(string $path, bool $deep): iterable
method retrievePaginatedListing (line 398) | private function retrievePaginatedListing(array $options): Generator
method move (line 408) | public function move(string $source, string $destination, Config $conf...
method copy (line 422) | public function copy(string $source, string $destination, Config $conf...
method readObject (line 459) | private function readObject(string $path, bool $wantsStream): StreamIn...
method publicUrl (line 476) | public function publicUrl(string $path, Config $config): string
method checksum (line 487) | public function checksum(string $path, Config $config): string
method temporaryUrl (line 508) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/AwsS3V3/AwsS3V3AdapterTest.php
class AwsS3V3AdapterTest (line 33) | class AwsS3V3AdapterTest extends FilesystemAdapterTestCase
method setUpBeforeClass (line 55) | public static function setUpBeforeClass(): void
method tearDown (line 60) | protected function tearDown(): void
method setUp (line 82) | protected function setUp(): void
method s3Client (line 91) | private static function s3Client(): S3ClientInterface
method writing_with_a_specific_mime_type (line 114) | public function writing_with_a_specific_mime_type(): void
method writing_a_file_with_explicit_mime_type (line 125) | public function writing_a_file_with_explicit_mime_type(): void
method issue_291 (line 138) | public function issue_291(): void
method listing_contents_recursive (line 150) | public function listing_contents_recursive(): void
method failing_to_delete_while_moving (line 171) | public function failing_to_delete_while_moving(): void
method issue_287 (line 187) | public function issue_287(): void
method failing_to_write_a_file (line 198) | public function failing_to_write_a_file(): void
method failing_to_delete_a_file (line 211) | public function failing_to_delete_a_file(): void
method fetching_unknown_mime_type_of_a_file (line 224) | public function fetching_unknown_mime_type_of_a_file(): void
method failing_to_retrieve_metadata (line 240) | public function failing_to_retrieve_metadata(Exception $exception, str...
method dpFailingMetadataGetters (line 253) | public static function dpFailingMetadataGetters(): iterable
method failing_to_check_for_file_existence (line 263) | public function failing_to_check_for_file_existence(): void
method streaming_reads_are_not_seekable_and_non_streaming_are (line 279) | public function streaming_reads_are_not_seekable_and_non_streaming_are...
method casesWhereHttpStreamingInfluencesSeekability (line 295) | public static function casesWhereHttpStreamingInfluencesSeekability():...
method configuring_http_streaming_via_options (line 306) | public function configuring_http_streaming_via_options(bool $streaming...
method use_globally_configured_options (line 323) | public function use_globally_configured_options(bool $streaming): void
method moving_with_updated_metadata (line 335) | public function moving_with_updated_metadata(): void
method moving_without_updated_metadata (line 352) | public function moving_without_updated_metadata(): void
method copying_with_updated_metadata (line 369) | public function copying_with_updated_metadata(): void
method setting_acl_via_options (line 386) | public function setting_acl_via_options(): void
method moving_a_file_with_visibility (line 404) | public function moving_a_file_with_visibility(): void
method specifying_a_custom_checksum_algo_is_not_supported (line 430) | public function specifying_a_custom_checksum_algo_is_not_supported(): ...
method copying_a_file_with_visibility (line 443) | public function copying_a_file_with_visibility(): void
method createFilesystemAdapter (line 462) | protected static function createFilesystemAdapter(bool $streaming = tr...
FILE: src/AwsS3V3/PortableVisibilityConverter.php
class PortableVisibilityConverter (line 9) | class PortableVisibilityConverter implements VisibilityConverter
method __construct (line 16) | public function __construct(private string $defaultForDirectories = Vi...
method visibilityToAcl (line 20) | public function visibilityToAcl(string $visibility): string
method aclToVisibility (line 29) | public function aclToVisibility(array $grants): string
method defaultForDirectories (line 43) | public function defaultForDirectories(): string
FILE: src/AwsS3V3/S3ClientStub.php
class S3ClientStub (line 22) | class S3ClientStub implements S3ClientInterface
method __construct (line 46) | public function __construct(S3ClientInterface $client)
method throwDuringUpload (line 51) | public function throwDuringUpload(Throwable $throwable): void
method upload (line 56) | public function upload($bucket, $key, $body, $acl = 'private', array $...
method failOnNextCopy (line 67) | public function failOnNextCopy(): void
method throwExceptionWhenExecutingCommand (line 72) | public function throwExceptionWhenExecutingCommand(string $commandName...
method throw500ExceptionWhenExecutingCommand (line 77) | public function throw500ExceptionWhenExecutingCommand(string $commandN...
method stageResultForCommand (line 85) | public function stageResultForCommand(string $commandName, ResultInter...
method execute (line 90) | public function execute(CommandInterface $command)
method getCommand (line 95) | public function getCommand($name, array $args = [])
method getHandlerList (line 100) | public function getHandlerList()
method getIterator (line 105) | public function getIterator($name, array $args = [])
method __call (line 110) | public function __call($name, array $arguments)
method executeAsync (line 115) | public function executeAsync(CommandInterface $command)
method getCredentials (line 135) | public function getCredentials()
method getRegion (line 140) | public function getRegion()
method getEndpoint (line 145) | public function getEndpoint()
method getApi (line 150) | public function getApi()
method getConfig (line 155) | public function getConfig($option = null)
method getPaginator (line 160) | public function getPaginator($name, array $args = [])
method waitUntil (line 165) | public function waitUntil($name, array $args = [])
method getWaiter (line 170) | public function getWaiter($name, array $args = [])
method createPresignedRequest (line 175) | public function createPresignedRequest(CommandInterface $command, $exp...
method getObjectUrl (line 180) | public function getObjectUrl($bucket, $key)
FILE: src/AwsS3V3/VisibilityConverter.php
type VisibilityConverter (line 7) | interface VisibilityConverter
method visibilityToAcl (line 9) | public function visibilityToAcl(string $visibility): string;
method aclToVisibility (line 10) | public function aclToVisibility(array $grants): string;
method defaultForDirectories (line 11) | public function defaultForDirectories(): string;
FILE: src/AzureBlobStorage/AzureBlobStorageAdapter.php
class AzureBlobStorageAdapter (line 46) | class AzureBlobStorageAdapter implements FilesystemAdapter, PublicUrlGen...
method __construct (line 62) | public function __construct(
method copy (line 75) | public function copy(string $source, string $destination, Config $conf...
method delete (line 92) | public function delete(string $path): void
method read (line 107) | public function read(string $path): string
method readStream (line 114) | public function readStream(string $path)
method listContents (line 127) | public function listContents(string $path, bool $deep = false): iterable
method fileExists (line 158) | public function fileExists(string $path): bool
method directoryExists (line 171) | public function directoryExists(string $path): bool
method deleteDirectory (line 187) | public function deleteDirectory(string $path): void
method createDirectory (line 212) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 217) | public function setVisibility(string $path, string $visibility): void
method visibility (line 224) | public function visibility(string $path): FileAttributes
method mimeType (line 229) | public function mimeType(string $path): FileAttributes
method lastModified (line 238) | public function lastModified(string $path): FileAttributes
method fileSize (line 247) | public function fileSize(string $path): FileAttributes
method move (line 256) | public function move(string $source, string $destination, Config $conf...
method write (line 266) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 271) | public function writeStream(string $path, $contents, Config $config): ...
method upload (line 279) | private function upload(string $destination, $contents, Config $config...
method fetchMetadata (line 300) | private function fetchMetadata(string $path): FileAttributes
method getOptionsFromConfig (line 308) | private function getOptionsFromConfig(Config $config): CreateBlockBlob...
method normalizeBlobProperties (line 331) | private function normalizeBlobProperties(string $path, BlobProperties ...
method publicUrl (line 343) | public function publicUrl(string $path, Config $config): string
method checksum (line 350) | public function checksum(string $path, Config $config): string
method temporaryUrl (line 372) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/AzureBlobStorage/AzureBlobStorageAdapterTest.php
class AzureBlobStorageAdapterTest (line 19) | class AzureBlobStorageAdapterTest extends TestCase
method createFilesystemAdapter (line 23) | protected static function createFilesystemAdapter(): FilesystemAdapter
method overwriting_a_file (line 45) | public function overwriting_a_file(): void
method setting_visibility (line 63) | public function setting_visibility(): void
method failing_to_set_visibility (line 71) | public function failing_to_set_visibility(): void
method failing_to_check_visibility (line 79) | public function failing_to_check_visibility(): void
method fetching_unknown_mime_type_of_a_file (line 84) | public function fetching_unknown_mime_type_of_a_file(): void
method listing_contents_recursive (line 89) | public function listing_contents_recursive(): void
method copying_a_file (line 97) | public function copying_a_file(): void
method moving_a_file (line 118) | public function moving_a_file(): void
method copying_a_file_again (line 143) | public function copying_a_file_again(): void
method setting_visibility_can_be_ignored_not_supported (line 164) | public function setting_visibility_can_be_ignored_not_supported(): void
method setting_visibility_causes_errors (line 178) | public function setting_visibility_causes_errors(): void
method checking_if_a_directory_exists_after_creating_it (line 191) | public function checking_if_a_directory_exists_after_creating_it(): void
method setting_visibility_on_a_file_that_does_not_exist (line 199) | public function setting_visibility_on_a_file_that_does_not_exist(): void
method creating_a_directory (line 207) | public function creating_a_directory(): void
FILE: src/CalculateChecksumFromStream.php
type CalculateChecksumFromStream (line 10) | trait CalculateChecksumFromStream
method calculateChecksumFromStream (line 12) | private function calculateChecksumFromStream(string $path, Config $con...
method readStream (line 29) | abstract public function readStream(string $path);
FILE: src/ChecksumAlgoIsNotSupported.php
class ChecksumAlgoIsNotSupported (line 8) | final class ChecksumAlgoIsNotSupported extends InvalidArgumentException
FILE: src/ChecksumProvider.php
type ChecksumProvider (line 5) | interface ChecksumProvider
method checksum (line 13) | public function checksum(string $path, Config $config): string;
FILE: src/Config.php
class Config (line 11) | class Config
method __construct (line 19) | public function __construct(private array $options = [])
method get (line 28) | public function get(string $property, $default = null)
method extend (line 33) | public function extend(array $options): Config
method withDefaults (line 38) | public function withDefaults(array $defaults): Config
method toArray (line 43) | public function toArray(): array
method withSetting (line 48) | public function withSetting(string $property, mixed $setting): Config
method withoutSettings (line 53) | public function withoutSettings(string ...$settings): Config
FILE: src/ConfigTest.php
class ConfigTest (line 9) | class ConfigTest extends TestCase
method a_config_object_exposes_passed_options (line 14) | public function a_config_object_exposes_passed_options(): void
method a_config_object_returns_a_default_value (line 23) | public function a_config_object_returns_a_default_value(): void
method extending_a_config_with_options (line 34) | public function extending_a_config_with_options(): void
method extending_with_defaults (line 47) | public function extending_with_defaults(): void
method extending_without_settings (line 60) | public function extending_without_settings(): void
FILE: src/CorruptedPathDetected.php
class CorruptedPathDetected (line 7) | final class CorruptedPathDetected extends RuntimeException implements Fi...
method forPath (line 9) | public static function forPath(string $path): CorruptedPathDetected
FILE: src/DecoratedAdapter.php
class DecoratedAdapter (line 7) | abstract class DecoratedAdapter implements FilesystemAdapter
method __construct (line 9) | public function __construct(protected FilesystemAdapter $adapter)
method fileExists (line 13) | public function fileExists(string $path): bool
method directoryExists (line 18) | public function directoryExists(string $path): bool
method write (line 23) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 28) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 33) | public function read(string $path): string
method readStream (line 38) | public function readStream(string $path)
method delete (line 43) | public function delete(string $path): void
method deleteDirectory (line 48) | public function deleteDirectory(string $path): void
method createDirectory (line 53) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 58) | public function setVisibility(string $path, string $visibility): void
method visibility (line 63) | public function visibility(string $path): FileAttributes
method mimeType (line 68) | public function mimeType(string $path): FileAttributes
method lastModified (line 73) | public function lastModified(string $path): FileAttributes
method fileSize (line 78) | public function fileSize(string $path): FileAttributes
method listContents (line 83) | public function listContents(string $path, bool $deep): iterable
method move (line 88) | public function move(string $source, string $destination, Config $conf...
method copy (line 93) | public function copy(string $source, string $destination, Config $conf...
FILE: src/DirectoryAttributes.php
class DirectoryAttributes (line 7) | class DirectoryAttributes implements StorageAttributes
method __construct (line 12) | public function __construct(
method path (line 21) | public function path(): string
method type (line 26) | public function type(): string
method visibility (line 31) | public function visibility(): ?string
method lastModified (line 36) | public function lastModified(): ?int
method extraMetadata (line 41) | public function extraMetadata(): array
method isFile (line 46) | public function isFile(): bool
method isDir (line 51) | public function isDir(): bool
method withPath (line 56) | public function withPath(string $path): self
method fromArray (line 64) | public static function fromArray(array $attributes): self
method jsonSerialize (line 77) | public function jsonSerialize(): array
FILE: src/DirectoryAttributesTest.php
class DirectoryAttributesTest (line 12) | class DirectoryAttributesTest extends TestCase
method exposing_some_values (line 17) | public function exposing_some_values(): void
method exposing_visibility (line 30) | public function exposing_visibility(): void
method exposing_last_modified (line 39) | public function exposing_last_modified(): void
method exposing_extra_meta_data (line 48) | public function exposing_extra_meta_data(): void
method serialization_capabilities (line 57) | public function serialization_capabilities(): void
FILE: src/DirectoryListing.php
class DirectoryListing (line 15) | class DirectoryListing implements IteratorAggregate
method __construct (line 20) | public function __construct(private iterable $listing)
method filter (line 29) | public function filter(callable $filter): DirectoryListing
method map (line 49) | public function map(callable $mapper): DirectoryListing
method sortByPath (line 63) | public function sortByPath(): DirectoryListing
method getIterator (line 77) | public function getIterator(): Traversable
method toArray (line 87) | public function toArray(): array
FILE: src/DirectoryListingTest.php
class DirectoryListingTest (line 15) | class DirectoryListingTest extends TestCase
method mapping_a_listing (line 20) | public function mapping_a_listing(): void
method mapping_a_listing_twice (line 37) | public function mapping_a_listing_twice(): void
method filter_a_listing (line 57) | public function filter_a_listing(): void
method filter_a_listing_twice (line 74) | public function filter_a_listing_twice(): void
method sorting_a_directory_listing (line 94) | public function sorting_a_directory_listing(): void
method iterating_over_storted_output (line 120) | public function iterating_over_storted_output(): void
method generateIntegers (line 137) | private function generateIntegers(int $min, int $max): Generator
FILE: src/ExceptionInformationTest.php
class ExceptionInformationTest (line 12) | class ExceptionInformationTest extends TestCase
method copy_exception_information (line 17) | public function copy_exception_information(): void
method create_directory_exception_information (line 28) | public function create_directory_exception_information(): void
method delete_directory_exception_information (line 39) | public function delete_directory_exception_information(): void
method delete_file_exception_information (line 51) | public function delete_file_exception_information(): void
method unable_to_check_for_file_existence (line 63) | public function unable_to_check_for_file_existence(): void
method unable_to_check_for_existence (line 72) | public function unable_to_check_for_existence(): void
method unable_to_check_for_directory_existence (line 81) | public function unable_to_check_for_directory_existence(): void
method move_file_exception_information (line 90) | public function move_file_exception_information(): void
method read_file_exception_information (line 101) | public function read_file_exception_information(): void
method retrieve_visibility_exception_information (line 113) | public function retrieve_visibility_exception_information(): void
method set_visibility_exception_information (line 125) | public function set_visibility_exception_information(): void
method write_file_exception_information (line 137) | public function write_file_exception_information(): void
method unreadable_file_exception_information (line 149) | public function unreadable_file_exception_information(): void
method symbolic_link_exception_information (line 159) | public function symbolic_link_exception_information(): void
method path_traversal_exception_information (line 169) | public function path_traversal_exception_information(): void
FILE: src/FileAttributes.php
class FileAttributes (line 7) | class FileAttributes implements StorageAttributes
method __construct (line 12) | public function __construct(
method type (line 23) | public function type(): string
method path (line 28) | public function path(): string
method fileSize (line 33) | public function fileSize(): ?int
method visibility (line 38) | public function visibility(): ?string
method lastModified (line 43) | public function lastModified(): ?int
method mimeType (line 48) | public function mimeType(): ?string
method extraMetadata (line 53) | public function extraMetadata(): array
method isFile (line 58) | public function isFile(): bool
method isDir (line 63) | public function isDir(): bool
method withPath (line 68) | public function withPath(string $path): self
method fromArray (line 76) | public static function fromArray(array $attributes): self
method jsonSerialize (line 88) | public function jsonSerialize(): array
FILE: src/FileAttributesTest.php
class FileAttributesTest (line 17) | class FileAttributesTest extends TestCase
method exposing_some_values (line 22) | public function exposing_some_values(): void
method exposing_all_values (line 38) | public function exposing_all_values(): void
method implements_array_access (line 53) | public function implements_array_access(): void
method properties_can_not_be_set (line 69) | public function properties_can_not_be_set(): void
method properties_can_not_be_unset (line 79) | public function properties_can_not_be_unset(): void
method json_transformations (line 91) | public function json_transformations(FileAttributes $attributes): void
method data_provider_for_json_transformation (line 98) | public static function data_provider_for_json_transformation(): Generator
FILE: src/Filesystem.php
class Filesystem (line 18) | class Filesystem implements FilesystemOperator
method __construct (line 25) | public function __construct(
method fileExists (line 36) | public function fileExists(string $location): bool
method directoryExists (line 41) | public function directoryExists(string $location): bool
method has (line 46) | public function has(string $location): bool
method write (line 53) | public function write(string $location, string $contents, array $confi...
method writeStream (line 62) | public function writeStream(string $location, $contents, array $config...
method read (line 74) | public function read(string $location): string
method readStream (line 79) | public function readStream(string $location)
method delete (line 84) | public function delete(string $location): void
method deleteDirectory (line 89) | public function deleteDirectory(string $location): void
method createDirectory (line 94) | public function createDirectory(string $location, array $config = []):...
method listContents (line 102) | public function listContents(string $location, bool $deep = self::LIST...
method pipeListing (line 110) | private function pipeListing(string $location, bool $deep, iterable $l...
method move (line 121) | public function move(string $source, string $destination, array $confi...
method copy (line 140) | public function copy(string $source, string $destination, array $confi...
method lastModified (line 159) | public function lastModified(string $path): int
method fileSize (line 164) | public function fileSize(string $path): int
method mimeType (line 169) | public function mimeType(string $path): string
method setVisibility (line 174) | public function setVisibility(string $path, string $visibility): void
method visibility (line 179) | public function visibility(string $path): string
method publicUrl (line 184) | public function publicUrl(string $path, array $config = []): string
method temporaryUrl (line 196) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
method checksum (line 211) | public function checksum(string $path, array $config = []): string
method resolvePublicUrlGenerator (line 232) | private function resolvePublicUrlGenerator(): ?PublicUrlGenerator
method assertIsResource (line 251) | private function assertIsResource($contents): void
method rewindStream (line 267) | private function rewindStream($resource): void
method resolveConfigForMoveAndCopy (line 274) | private function resolveConfigForMoveAndCopy(array $config): Config
FILE: src/FilesystemAdapter.php
type FilesystemAdapter (line 7) | interface FilesystemAdapter
method fileExists (line 13) | public function fileExists(string $path): bool;
method directoryExists (line 19) | public function directoryExists(string $path): bool;
method write (line 25) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 33) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 39) | public function read(string $path): string;
method readStream (line 47) | public function readStream(string $path);
method delete (line 53) | public function delete(string $path): void;
method deleteDirectory (line 59) | public function deleteDirectory(string $path): void;
method createDirectory (line 65) | public function createDirectory(string $path, Config $config): void;
method setVisibility (line 71) | public function setVisibility(string $path, string $visibility): void;
method visibility (line 77) | public function visibility(string $path): FileAttributes;
method mimeType (line 83) | public function mimeType(string $path): FileAttributes;
method lastModified (line 89) | public function lastModified(string $path): FileAttributes;
method fileSize (line 95) | public function fileSize(string $path): FileAttributes;
method listContents (line 102) | public function listContents(string $path, bool $deep): iterable;
method move (line 108) | public function move(string $source, string $destination, Config $conf...
method copy (line 114) | public function copy(string $source, string $destination, Config $conf...
FILE: src/FilesystemException.php
type FilesystemException (line 9) | interface FilesystemException extends Throwable
FILE: src/FilesystemOperationFailed.php
type FilesystemOperationFailed (line 7) | interface FilesystemOperationFailed extends FilesystemException
method operation (line 24) | public function operation(): string;
FILE: src/FilesystemOperator.php
type FilesystemOperator (line 7) | interface FilesystemOperator extends FilesystemReader, FilesystemWriter
FILE: src/FilesystemReader.php
type FilesystemReader (line 17) | interface FilesystemReader
method fileExists (line 26) | public function fileExists(string $location): bool;
method directoryExists (line 32) | public function directoryExists(string $location): bool;
method has (line 38) | public function has(string $location): bool;
method read (line 44) | public function read(string $location): string;
method readStream (line 52) | public function readStream(string $location);
method listContents (line 60) | public function listContents(string $location, bool $deep = self::LIST...
method lastModified (line 66) | public function lastModified(string $path): int;
method fileSize (line 72) | public function fileSize(string $path): int;
method mimeType (line 78) | public function mimeType(string $path): string;
method visibility (line 84) | public function visibility(string $path): string;
FILE: src/FilesystemTest.php
class FilesystemTest (line 25) | class FilesystemTest extends TestCase
method setupFilesystem (line 37) | public function setupFilesystem(): void
method removeFiles (line 47) | public function removeFiles(): void
method writing_and_reading_files (line 55) | public function writing_and_reading_files(): void
method trying_to_write_with_an_invalid_stream_arguments (line 70) | public function trying_to_write_with_an_invalid_stream_arguments($inpu...
method invalidStreamInput (line 77) | public static function invalidStreamInput(): Generator
method writing_and_reading_a_stream (line 88) | public function writing_and_reading_a_stream(): void
method writing_using_a_stream_wrapper (line 106) | public function writing_using_a_stream_wrapper(): void
method checking_if_files_exist (line 121) | public function checking_if_files_exist(): void
method checking_if_directories_exist (line 135) | public function checking_if_directories_exist(): void
method deleting_a_file (line 149) | public function deleting_a_file(): void
method creating_a_directory (line 160) | public function creating_a_directory(): void
method deleting_a_directory (line 172) | public function deleting_a_directory(): void
method listing_directory_contents (line 192) | public function listing_directory_contents(): void
method listing_directory_contents_recursive (line 211) | public function listing_directory_contents_recursive(): void
method copying_files (line 227) | public function copying_files(): void
method moving_files (line 240) | public function moving_files(): void
method fetching_last_modified (line 253) | public function fetching_last_modified(): void
method fetching_mime_type (line 267) | public function fetching_mime_type(): void
method fetching_file_size (line 279) | public function fetching_file_size(): void
method ensuring_streams_are_rewound_when_writing (line 291) | public function ensuring_streams_are_rewound_when_writing(): void
method setting_visibility (line 305) | public function setting_visibility(): void
method protecting_against_path_traversals (line 324) | public function protecting_against_path_traversals(callable $scenario)...
method scenariosCausingPathTraversal (line 330) | public static function scenariosCausingPathTraversal(): Generator
method listing_exceptions_are_uniformely_represented (line 396) | public function listing_exceptions_are_uniformely_represented(): void
method failing_to_create_a_public_url (line 417) | public function failing_to_create_a_public_url(): void
method not_configuring_a_public_url (line 436) | public function not_configuring_a_public_url(): void
method creating_a_public_url (line 448) | public function creating_a_public_url(): void
method public_url_array_uses_multi_prefixer (line 463) | public function public_url_array_uses_multi_prefixer(): void
method custom_public_url_generator (line 486) | public function custom_public_url_generator(): void
method copying_from_and_to_the_same_location_fails (line 505) | public function copying_from_and_to_the_same_location_fails(): void
method moving_from_and_to_the_same_location_fails (line 516) | public function moving_from_and_to_the_same_location_fails(): void
method get_checksum_for_adapter_that_supports (line 527) | public function get_checksum_for_adapter_that_supports(): void
method get_checksum_for_adapter_that_does_not_support (line 537) | public function get_checksum_for_adapter_that_does_not_support(): void
method get_checksum_for_adapter_that_does_not_support_specific_algo (line 549) | public function get_checksum_for_adapter_that_does_not_support_specifi...
method get_sha256_checksum_for_adapter_that_does_not_support (line 567) | public function get_sha256_checksum_for_adapter_that_does_not_support(...
method get_sha256_checksum_for_adapter_that_does_not_support_while_crc32c_is_the_default (line 579) | public function get_sha256_checksum_for_adapter_that_does_not_support_...
method unable_to_get_checksum_for_for_file_that_does_not_exist (line 592) | public function unable_to_get_checksum_for_for_file_that_does_not_exis...
method generating_temporary_urls (line 604) | public function generating_temporary_urls(): void
method not_being_able_to_generate_temporary_urls (line 626) | public function not_being_able_to_generate_temporary_urls(): void
method ignoring_same_paths_for_move_and_copy (line 638) | public function ignoring_same_paths_for_move_and_copy(): void
method failing_same_paths_for_move (line 657) | public function failing_same_paths_for_move(): void
method failing_same_paths_for_copy (line 673) | public function failing_same_paths_for_copy(): void
method unable_to_get_checksum_directory (line 689) | public function unable_to_get_checksum_directory(): void
method moving_a_file_with_visibility_scenario (line 704) | public function moving_a_file_with_visibility_scenario(
method copying_a_file_with_visibility_scenario (line 730) | public function copying_a_file_with_visibility_scenario(
method fileMoveOrCopyScenarios (line 751) | public static function fileMoveOrCopyScenarios(): iterable
FILE: src/FilesystemWriter.php
type FilesystemWriter (line 7) | interface FilesystemWriter
method write (line 13) | public function write(string $location, string $contents, array $confi...
method writeStream (line 21) | public function writeStream(string $location, $contents, array $config...
method setVisibility (line 27) | public function setVisibility(string $path, string $visibility): void;
method delete (line 33) | public function delete(string $location): void;
method deleteDirectory (line 39) | public function deleteDirectory(string $location): void;
method createDirectory (line 45) | public function createDirectory(string $location, array $config = []):...
method move (line 51) | public function move(string $source, string $destination, array $confi...
method copy (line 57) | public function copy(string $source, string $destination, array $confi...
FILE: src/Ftp/ConnectionProvider.php
type ConnectionProvider (line 7) | interface ConnectionProvider
method createConnection (line 12) | public function createConnection(FtpConnectionOptions $options);
FILE: src/Ftp/ConnectivityChecker.php
type ConnectivityChecker (line 7) | interface ConnectivityChecker
method isConnected (line 12) | public function isConnected($connection): bool;
FILE: src/Ftp/ConnectivityCheckerThatCanFail.php
class ConnectivityCheckerThatCanFail (line 7) | class ConnectivityCheckerThatCanFail implements ConnectivityChecker
method __construct (line 11) | public function __construct(private ConnectivityChecker $connectivityC...
method failNextCall (line 15) | public function failNextCall(): void
method isConnected (line 23) | public function isConnected($connection): bool
FILE: src/Ftp/FtpAdapter.php
class FtpAdapter (line 37) | class FtpAdapter implements FilesystemAdapter
method __construct (line 58) | public function __construct(
method __destruct (line 77) | public function __destruct()
method connection (line 85) | private function connection()
method disconnect (line 106) | public function disconnect(): void
method isPureFtpdServer (line 114) | private function isPureFtpdServer(): bool
method isServerSupportingListOptions (line 125) | private function isServerSupportingListOptions(): bool
method fileExists (line 138) | public function fileExists(string $path): bool
method write (line 149) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 161) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 186) | public function read(string $path): string
method readStream (line 195) | public function readStream(string $path)
method delete (line 212) | public function delete(string $path): void
method deleteFile (line 221) | private function deleteFile(string $path, $connection): void
method deleteDirectory (line 231) | public function deleteDirectory(string $path): void
method createDirectory (line 259) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 264) | public function setVisibility(string $path, string $visibility): void
method fetchMetadata (line 275) | private function fetchMetadata(string $path, string $type): FileAttrib...
method mimeType (line 302) | public function mimeType(string $path): FileAttributes
method lastModified (line 319) | public function lastModified(string $path): FileAttributes
method visibility (line 332) | public function visibility(string $path): FileAttributes
method fileSize (line 337) | public function fileSize(string $path): FileAttributes
method listContents (line 350) | public function listContents(string $path, bool $deep): iterable
method normalizeListing (line 365) | private function normalizeListing(array $listing, string $prefix = '')...
method normalizeObject (line 383) | private function normalizeObject(string $item, string $base): StorageA...
method detectSystemType (line 394) | private function detectSystemType(string $item): string
method normalizeWindowsObject (line 402) | private function normalizeWindowsObject(string $item, string $base): S...
method normalizeUnixObject (line 426) | private function normalizeUnixObject(string $item, string $base): Stor...
method listingItemIsDirectory (line 458) | private function listingItemIsDirectory(string $permissions): bool
method normalizeUnixTimestamp (line 463) | private function normalizeUnixTimestamp(string $month, string $day, st...
method normalizePermissions (line 479) | private function normalizePermissions(string $permissions): int
method listDirectoryContentsRecursive (line 502) | private function listDirectoryContentsRecursive(string $directory): Ge...
method ftpRawlist (line 524) | private function ftpRawlist(string $options, string $path): array
method move (line 541) | public function move(string $source, string $destination, Config $conf...
method copy (line 558) | public function copy(string $source, string $destination, Config $conf...
method ensureParentDirectoryExists (line 577) | private function ensureParentDirectoryExists(string $path, ?string $vi...
method ensureDirectoryExists (line 588) | private function ensureDirectoryExists(string $dirname, ?string $visib...
method escapePath (line 621) | private function escapePath(string $path): string
method hasFtpConnection (line 629) | private function hasFtpConnection(): bool
method directoryExists (line 634) | public function directoryExists(string $path): bool
method resolveConnectionRoot (line 645) | private function resolveConnectionRoot($connection): string
method prefixer (line 667) | private function prefixer(): PathPrefixer
FILE: src/Ftp/FtpAdapterTest.php
class FtpAdapterTest (line 15) | class FtpAdapterTest extends FtpAdapterTestCase
method createFilesystemAdapter (line 17) | protected static function createFilesystemAdapter(): FilesystemAdapter
method disconnect_after_destruct (line 41) | public function disconnect_after_destruct(): void
method it_can_disconnect (line 61) | public function it_can_disconnect(): void
method not_being_able_to_resolve_connection_root (line 76) | public function not_being_able_to_resolve_connection_root(): void
method not_being_able_to_resolve_connection_root_pwd (line 97) | public function not_being_able_to_resolve_connection_root_pwd(): void
method tearDown (line 115) | protected function tearDown(): void
FILE: src/Ftp/FtpAdapterTestCase.php
class FtpAdapterTestCase (line 27) | abstract class FtpAdapterTestCase extends FilesystemAdapterTestCase
method setUp (line 29) | protected function setUp(): void
method resetFunctionMocks (line 42) | public function resetFunctionMocks(): void
method clearFilesystemAdapterCache (line 47) | public static function clearFilesystemAdapterCache(): void
method using_empty_string_for_root (line 56) | public function using_empty_string_for_root(): void
method reconnecting_after_failure (line 80) | public function reconnecting_after_failure(): void
method reading_a_file_twice_for_issue_1522 (line 96) | public function reading_a_file_twice_for_issue_1522(): void
method failing_to_write_a_file (line 113) | public function failing_to_write_a_file(callable $scenario): void
method scenariosCausingWriteFailure (line 129) | public static function scenariosCausingWriteFailure(): Generator
method scenarios_causing_directory_deletion_to_fail (line 153) | public function scenarios_causing_directory_deletion_to_fail(callable ...
method scenariosCausingDirectoryDeleteFailure (line 165) | public static function scenariosCausingDirectoryDeleteFailure(): Gener...
method failing_to_copy (line 181) | public function failing_to_copy(callable $scenario): void
method failing_to_move_because_creating_the_directory_fails (line 196) | public function failing_to_move_because_creating_the_directory_fails()...
method scenariosCausingCopyFailure (line 208) | public static function scenariosCausingCopyFailure(): Generator
method failing_to_delete_a_file (line 222) | public function failing_to_delete_a_file(): void
method formatting_a_directory_listing_with_a_total_indicator (line 237) | public function formatting_a_directory_listing_with_a_total_indicator(...
method receiving_a_windows_listing (line 259) | public function receiving_a_windows_listing(): void
method receiving_an_invalid_windows_listing (line 279) | public function receiving_an_invalid_windows_listing(): void
method getting_an_invalid_listing_response_for_unix_listings (line 297) | public function getting_an_invalid_listing_response_for_unix_listings(...
method failing_to_get_the_file_size_of_a_directory (line 316) | public function failing_to_get_the_file_size_of_a_directory(): void
method formatting_non_manual_recursive_listings (line 334) | public function formatting_non_manual_recursive_listings(): void
method filenames_and_dirnames_with_spaces_are_supported (line 378) | public function filenames_and_dirnames_with_spaces_are_supported(): void
FILE: src/Ftp/FtpConnectionException.php
type FtpConnectionException (line 9) | interface FtpConnectionException extends FilesystemException
FILE: src/Ftp/FtpConnectionOptions.php
class FtpConnectionOptions (line 9) | class FtpConnectionOptions
method __construct (line 11) | public function __construct(
method host (line 30) | public function host(): string
method root (line 35) | public function root(): string
method username (line 40) | public function username(): string
method password (line 45) | public function password(): string
method port (line 50) | public function port(): int
method ssl (line 55) | public function ssl(): bool
method timeout (line 60) | public function timeout(): int
method utf8 (line 65) | public function utf8(): bool
method passive (line 70) | public function passive(): bool
method transferMode (line 75) | public function transferMode(): int
method systemType (line 80) | public function systemType(): ?string
method ignorePassiveAddress (line 85) | public function ignorePassiveAddress(): ?bool
method timestampsOnUnixListingsEnabled (line 90) | public function timestampsOnUnixListingsEnabled(): bool
method recurseManually (line 95) | public function recurseManually(): bool
method useRawListOptions (line 100) | public function useRawListOptions(): ?bool
method fromArray (line 105) | public static function fromArray(array $options): FtpConnectionOptions
FILE: src/Ftp/FtpConnectionProvider.php
class FtpConnectionProvider (line 11) | class FtpConnectionProvider implements ConnectionProvider
method createConnection (line 18) | public function createConnection(FtpConnectionOptions $options)
method createConnectionResource (line 43) | private function createConnectionResource(string $host, int $port, int...
method authenticate (line 58) | private function authenticate(FtpConnectionOptions $options, $connecti...
method enableUtf8Mode (line 68) | private function enableUtf8Mode(FtpConnectionOptions $options, $connec...
method ignorePassiveAddress (line 86) | private function ignorePassiveAddress(FtpConnectionOptions $options, $...
method makeConnectionPassive (line 102) | private function makeConnectionPassive(FtpConnectionOptions $options, ...
FILE: src/Ftp/FtpConnectionProviderTest.php
class FtpConnectionProviderTest (line 15) | class FtpConnectionProviderTest extends TestCase
method setUp (line 24) | protected function setUp(): void
method setupConnectionProvider (line 32) | public function setupConnectionProvider(): void
method resetFunctionMocks (line 40) | public function resetFunctionMocks(): void
method connecting_successfully (line 48) | public function connecting_successfully(): void
method not_being_able_to_enable_uft8_mode (line 70) | public function not_being_able_to_enable_uft8_mode(): void
method uft8_mode_already_active_by_server (line 93) | public function uft8_mode_already_active_by_server(): void
method not_being_able_to_ignore_the_passive_address (line 115) | public function not_being_able_to_ignore_the_passive_address(): void
method not_being_able_to_make_the_connection_passive (line 138) | public function not_being_able_to_make_the_connection_passive(): void
method not_being_able_to_connect (line 161) | public function not_being_able_to_connect(): void
method not_being_able_to_connect_over_ssl (line 181) | public function not_being_able_to_connect_over_ssl(): void
method not_being_able_to_authenticate (line 202) | public function not_being_able_to_authenticate(): void
FILE: src/Ftp/FtpdAdapterTest.php
class FtpdAdapterTest (line 12) | class FtpdAdapterTest extends FtpAdapterTestCase
method createFilesystemAdapter (line 14) | protected static function createFilesystemAdapter(): FilesystemAdapter
FILE: src/Ftp/InvalidListResponseReceived.php
class InvalidListResponseReceived (line 10) | class InvalidListResponseReceived extends RuntimeException implements Fi...
FILE: src/Ftp/NoopCommandConnectivityChecker.php
class NoopCommandConnectivityChecker (line 10) | class NoopCommandConnectivityChecker implements ConnectivityChecker
method isConnected (line 12) | public function isConnected($connection): bool
FILE: src/Ftp/NoopCommandConnectivityCheckerTest.php
class NoopCommandConnectivityCheckerTest (line 13) | class NoopCommandConnectivityCheckerTest extends TestCase
method setUp (line 17) | protected function setUp(): void
method detecting_a_good_connection (line 25) | public function detecting_a_good_connection(): void
method detecting_a_closed_connection (line 43) | public function detecting_a_closed_connection(): void
FILE: src/Ftp/RawListFtpConnectivityChecker.php
class RawListFtpConnectivityChecker (line 9) | class RawListFtpConnectivityChecker implements ConnectivityChecker
method isConnected (line 14) | public function isConnected($connection): bool
FILE: src/Ftp/RawListFtpConnectivityCheckerTest.php
class RawListFtpConnectivityCheckerTest (line 11) | class RawListFtpConnectivityCheckerTest extends TestCase
method detecting_if_a_connection_is_connected (line 17) | public function detecting_if_a_connection_is_connected(): void
FILE: src/Ftp/StubConnectionProvider.php
class StubConnectionProvider (line 6) | class StubConnectionProvider implements ConnectionProvider
method __construct (line 10) | public function __construct(private ConnectionProvider $provider)
method createConnection (line 14) | public function createConnection(FtpConnectionOptions $options)
FILE: src/Ftp/UnableToAuthenticate.php
class UnableToAuthenticate (line 9) | final class UnableToAuthenticate extends RuntimeException implements Ftp...
method __construct (line 11) | public function __construct()
FILE: src/Ftp/UnableToConnectToFtpHost.php
class UnableToConnectToFtpHost (line 9) | final class UnableToConnectToFtpHost extends RuntimeException implements...
method forHost (line 11) | public static function forHost(string $host, int $port, bool $ssl, str...
FILE: src/Ftp/UnableToEnableUtf8Mode.php
class UnableToEnableUtf8Mode (line 9) | final class UnableToEnableUtf8Mode extends RuntimeException implements F...
FILE: src/Ftp/UnableToMakeConnectionPassive.php
class UnableToMakeConnectionPassive (line 9) | class UnableToMakeConnectionPassive extends RuntimeException implements ...
FILE: src/Ftp/UnableToResolveConnectionRoot.php
class UnableToResolveConnectionRoot (line 10) | final class UnableToResolveConnectionRoot extends RuntimeException imple...
method __construct (line 12) | private function __construct(string $message, ?Throwable $previous = n...
method itDoesNotExist (line 17) | public static function itDoesNotExist(string $root, string $reason = '...
method couldNotGetCurrentDirectory (line 24) | public static function couldNotGetCurrentDirectory(string $message = '...
FILE: src/Ftp/UnableToSetFtpOption.php
class UnableToSetFtpOption (line 9) | class UnableToSetFtpOption extends RuntimeException implements FtpConnec...
method whileSettingOption (line 11) | public static function whileSettingOption(string $option): UnableToSet...
FILE: src/GoogleCloudStorage/GoogleCloudStorageAdapter.php
class GoogleCloudStorageAdapter (line 46) | class GoogleCloudStorageAdapter implements FilesystemAdapter, PublicUrlG...
method __construct (line 58) | public function __construct(
method publicUrl (line 71) | public function publicUrl(string $path, Config $config): string
method fileExists (line 78) | public function fileExists(string $path): bool
method directoryExists (line 89) | public function directoryExists(string $path): bool
method write (line 119) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 124) | public function writeStream(string $path, $contents, Config $config): ...
method upload (line 132) | private function upload(string $path, $contents, Config $config): void
method read (line 160) | public function read(string $path): string
method readStream (line 171) | public function readStream(string $path)
method delete (line 195) | public function delete(string $path): void
method deleteDirectory (line 207) | public function deleteDirectory(string $path): void
method createDirectory (line 225) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 234) | public function setVisibility(string $path, string $visibility): void
method visibility (line 245) | public function visibility(string $path): FileAttributes
method mimeType (line 258) | public function mimeType(string $path): FileAttributes
method lastModified (line 263) | public function lastModified(string $path): FileAttributes
method fileSize (line 268) | public function fileSize(string $path): FileAttributes
method fileAttributes (line 273) | private function fileAttributes(string $path, string $type): FileAttri...
method storageObjectToStorageAttributes (line 292) | public function storageObjectToStorageAttributes(StorageObject $object...
method listContents (line 308) | public function listContents(string $path, bool $deep): iterable
method move (line 342) | public function move(string $source, string $destination, Config $conf...
method copy (line 352) | public function copy(string $source, string $destination, Config $conf...
method checksum (line 377) | public function checksum(string $path, Config $config): string
method temporaryUrl (line 398) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/GoogleCloudStorage/GoogleCloudStorageAdapterTest.php
class GoogleCloudStorageAdapterTest (line 20) | class GoogleCloudStorageAdapterTest extends FilesystemAdapterTestCase
method setUpBeforeClass (line 29) | public static function setUpBeforeClass(): void
method bucketName (line 35) | protected static function bucketName(): string|array|false
method visibilityHandler (line 40) | protected static function visibilityHandler(): VisibilityHandler
method prefixPath (line 45) | public function prefixPath(string $path): string
method prefixDirectoryPath (line 50) | public function prefixDirectoryPath(string $path): string
method createFilesystemAdapter (line 55) | protected static function createFilesystemAdapter(): FilesystemAdapter
method writing_with_specific_metadata (line 80) | public function writing_with_specific_metadata(): void
method guessing_the_mime_type_when_writing (line 91) | public function guessing_the_mime_type_when_writing(): void
method fetching_visibility_of_non_existing_file (line 102) | public function fetching_visibility_of_non_existing_file(): void
method fetching_unknown_mime_type_of_a_file (line 114) | public function fetching_unknown_mime_type_of_a_file(): void
method listing_a_toplevel_directory (line 122) | public function listing_a_toplevel_directory(): void
method failing_to_write_a_file (line 131) | public function failing_to_write_a_file(): void
method failing_to_delete_a_file (line 144) | public function failing_to_delete_a_file(): void
method failing_to_delete_a_directory (line 157) | public function failing_to_delete_a_directory(): void
method failing_to_retrieve_visibility (line 172) | public function failing_to_retrieve_visibility(): void
FILE: src/GoogleCloudStorage/GoogleCloudStorageAdapterWithoutAclTest.php
class GoogleCloudStorageAdapterWithoutAclTest (line 6) | class GoogleCloudStorageAdapterWithoutAclTest extends GoogleCloudStorage...
method visibilityHandler (line 8) | protected static function visibilityHandler(): VisibilityHandler
method bucketName (line 13) | protected static function bucketName(): string|array|false
FILE: src/GoogleCloudStorage/PortableVisibilityHandler.php
class PortableVisibilityHandler (line 12) | class PortableVisibilityHandler implements VisibilityHandler
method __construct (line 20) | public function __construct(
method setVisibility (line 27) | public function setVisibility(StorageObject $object, string $visibilit...
method determineVisibility (line 36) | public function determineVisibility(StorageObject $object): string
method visibilityToPredefinedAcl (line 49) | public function visibilityToPredefinedAcl(string $visibility): string
FILE: src/GoogleCloudStorage/StubRiggedBucket.php
class StubRiggedBucket (line 11) | class StubRiggedBucket extends Bucket
method failForObject (line 15) | public function failForObject(string $name, ?Throwable $throwable = nu...
method failForUpload (line 20) | public function failForUpload(string $name, ?Throwable $throwable = nu...
method object (line 25) | public function object($name, array $options = [])
method upload (line 32) | public function upload($data, array $options = [])
method setupTrigger (line 39) | private function setupTrigger(string $method, string $name, ?Throwable...
method pushTrigger (line 44) | private function pushTrigger(string $method, string $name): void
FILE: src/GoogleCloudStorage/StubStorageClient.php
class StubStorageClient (line 10) | class StubStorageClient extends StorageClient
method __construct (line 14) | public function __construct(array $config = [])
method bucket (line 24) | public function bucket($name, $userProject = false, array $options = [])
FILE: src/GoogleCloudStorage/UniformBucketLevelAccessVisibility.php
class UniformBucketLevelAccessVisibility (line 9) | class UniformBucketLevelAccessVisibility implements VisibilityHandler
method setVisibility (line 13) | public function setVisibility(StorageObject $object, string $visibilit...
method determineVisibility (line 18) | public function determineVisibility(StorageObject $object): string
method visibilityToPredefinedAcl (line 23) | public function visibilityToPredefinedAcl(string $visibility): string
FILE: src/GoogleCloudStorage/VisibilityHandler.php
type VisibilityHandler (line 9) | interface VisibilityHandler
method setVisibility (line 11) | public function setVisibility(StorageObject $object, string $visibilit...
method determineVisibility (line 12) | public function determineVisibility(StorageObject $object): string;
method visibilityToPredefinedAcl (line 13) | public function visibilityToPredefinedAcl(string $visibility): string;
FILE: src/GridFS/GridFSAdapter.php
class GridFSAdapter (line 33) | class GridFSAdapter implements FilesystemAdapter
method __construct (line 49) | public function __construct(
method fileExists (line 59) | public function fileExists(string $path): bool
method directoryExists (line 66) | public function directoryExists(string $path): bool
method write (line 78) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 104) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 126) | public function read(string $path): string
method readStream (line 136) | public function readStream(string $path)
method delete (line 159) | public function delete(string $path): void
method deleteDirectory (line 173) | public function deleteDirectory(string $path): void
method createDirectory (line 183) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 204) | public function setVisibility(string $path, string $visibility): void
method visibility (line 222) | public function visibility(string $path): FileAttributes
method fileSize (line 233) | public function fileSize(string $path): FileAttributes
method mimeType (line 247) | public function mimeType(string $path): FileAttributes
method lastModified (line 266) | public function lastModified(string $path): FileAttributes
method listContents (line 280) | public function listContents(string $path, bool $deep): iterable
method move (line 346) | public function move(string $source, string $destination, Config $conf...
method copy (line 370) | public function copy(string $source, string $destination, Config $conf...
method findFile (line 402) | private function findFile(string $path): ?array
method mapFileAttributes (line 416) | private function mapFileAttributes(array $file): FileAttributes
method findAndDelete (line 431) | private function findAndDelete(array $filter): void
FILE: src/GridFS/GridFSAdapterTest.php
class GridFSAdapterTest (line 25) | class GridFSAdapterTest extends TestCase
method tearDownAfterClass (line 32) | public static function tearDownAfterClass(): void
method fetching_contains_extra_metadata (line 42) | public function fetching_contains_extra_metadata(): void
method fetching_last_modified_of_a_directory (line 58) | public function fetching_last_modified_of_a_directory(): void
method fetching_mime_type_of_a_directory (line 73) | public function fetching_mime_type_of_a_directory(): void
method reading_a_file_with_trailing_slash (line 88) | public function reading_a_file_with_trailing_slash(): void
method reading_a_file_stream_with_trailing_slash (line 97) | public function reading_a_file_stream_with_trailing_slash(): void
method writing_a_file_with_trailing_slash (line 106) | public function writing_a_file_with_trailing_slash(): void
method writing_a_file_stream_with_trailing_slash (line 115) | public function writing_a_file_stream_with_trailing_slash(): void
method writing_a_file_with_a_invalid_stream (line 125) | public function writing_a_file_with_a_invalid_stream(): void
method delete_a_file_with_trailing_slash (line 135) | public function delete_a_file_with_trailing_slash(): void
method reading_last_revision (line 144) | public function reading_last_revision(): void
method listing_contents_last_revision (line 163) | public function listing_contents_last_revision(bool $deep): void
method listing_contents_directory_with_multiple_files (line 185) | public function listing_contents_directory_with_multiple_files(): void
method delete_all_revisions (line 207) | public function delete_all_revisions(): void
method move_all_revisions (line 227) | public function move_all_revisions(): void
method tearDown (line 245) | protected function tearDown(): void
method createFilesystemAdapter (line 252) | protected static function createFilesystemAdapter(): FilesystemAdapter
method getDatabase (line 260) | private static function getDatabase(): Database
FILE: src/InMemory/InMemoryFile.php
class InMemoryFile (line 13) | class InMemoryFile
method updateContents (line 19) | public function updateContents(string $contents, ?int $timestamp): void
method lastModified (line 25) | public function lastModified(): int
method withLastModified (line 30) | public function withLastModified(int $lastModified): self
method read (line 38) | public function read(): string
method readStream (line 46) | public function readStream()
method fileSize (line 56) | public function fileSize(): int
method mimeType (line 61) | public function mimeType(): string
method setVisibility (line 66) | public function setVisibility(string $visibility): void
method visibility (line 71) | public function visibility(): ?string
FILE: src/InMemory/InMemoryFilesystemAdapter.php
class InMemoryFilesystemAdapter (line 23) | class InMemoryFilesystemAdapter implements FilesystemAdapter
method __construct (line 33) | public function __construct(
method fileExists (line 40) | public function fileExists(string $path): bool
method write (line 45) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 55) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 60) | public function read(string $path): string
method readStream (line 71) | public function readStream(string $path)
method delete (line 82) | public function delete(string $path): void
method deleteDirectory (line 87) | public function deleteDirectory(string $path): void
method createDirectory (line 99) | public function createDirectory(string $path, Config $config): void
method directoryExists (line 105) | public function directoryExists(string $path): bool
method setVisibility (line 119) | public function setVisibility(string $path, string $visibility): void
method visibility (line 130) | public function visibility(string $path): FileAttributes
method mimeType (line 141) | public function mimeType(string $path): FileAttributes
method lastModified (line 158) | public function lastModified(string $path): FileAttributes
method fileSize (line 169) | public function fileSize(string $path): FileAttributes
method listContents (line 180) | public function listContents(string $path, bool $deep): iterable
method move (line 221) | public function move(string $source, string $destination, Config $conf...
method copy (line 240) | public function copy(string $source, string $destination, Config $conf...
method preparePath (line 257) | private function preparePath(string $path): string
method deleteEverything (line 262) | public function deleteEverything(): void
FILE: src/InMemory/InMemoryFilesystemAdapterTest.php
class InMemoryFilesystemAdapterTest (line 22) | class InMemoryFilesystemAdapterTest extends FilesystemAdapterTestCase
method resetFunctionMocks (line 29) | public function resetFunctionMocks(): void
method getting_mimetype_on_a_non_existing_file (line 40) | public function getting_mimetype_on_a_non_existing_file(): void
method getting_last_modified_on_a_non_existing_file (line 49) | public function getting_last_modified_on_a_non_existing_file(): void
method getting_file_size_on_a_non_existing_file (line 58) | public function getting_file_size_on_a_non_existing_file(): void
method deleting_a_file (line 67) | public function deleting_a_file(): void
method deleting_a_directory (line 78) | public function deleting_a_directory(): void
method creating_a_directory_does_nothing (line 95) | public function creating_a_directory_does_nothing(): void
method writing_with_a_stream_and_reading_a_file (line 104) | public function writing_with_a_stream_and_reading_a_file(): void
method reading_a_stream (line 115) | public function reading_a_stream(): void
method reading_a_non_existing_file (line 126) | public function reading_a_non_existing_file(): void
method stream_reading_a_non_existing_file (line 135) | public function stream_reading_a_non_existing_file(): void
method listing_all_files (line 144) | public function listing_all_files(): void
method listing_non_recursive (line 171) | public function listing_non_recursive(): void
method moving_a_file_successfully (line 184) | public function moving_a_file_successfully(): void
method trying_to_move_a_non_existing_file (line 196) | public function trying_to_move_a_non_existing_file(): void
method copying_a_file_successfully (line 205) | public function copying_a_file_successfully(): void
method trying_to_copy_a_non_existing_file (line 217) | public function trying_to_copy_a_non_existing_file(): void
method not_listing_directory_placeholders (line 226) | public function not_listing_directory_placeholders(): void
method checking_for_metadata (line 238) | public function checking_for_metadata(): void
method fetching_unknown_mime_type_of_a_file (line 257) | public function fetching_unknown_mime_type_of_a_file(): void
method using_custom_timestamp (line 266) | public function using_custom_timestamp(): void
method createFilesystemAdapter (line 279) | protected static function createFilesystemAdapter(): FilesystemAdapter
FILE: src/InMemory/StaticInMemoryAdapterRegistry.php
class StaticInMemoryAdapterRegistry (line 5) | class StaticInMemoryAdapterRegistry
method get (line 10) | public static function get(string $name = 'default'): InMemoryFilesyst...
method deleteAllFilesystems (line 15) | public static function deleteAllFilesystems(): void
FILE: src/InMemory/StaticInMemoryAdapterRegistryTest.php
class StaticInMemoryAdapterRegistryTest (line 8) | class StaticInMemoryAdapterRegistryTest extends InMemoryFilesystemAdapte...
method using_different_name_to_segment_adapters (line 13) | public function using_different_name_to_segment_adapters(): void
method files_persist_between_instances (line 30) | public function files_persist_between_instances(): void
method tearDown (line 48) | protected function tearDown(): void
method createFilesystemAdapter (line 53) | protected static function createFilesystemAdapter(): FilesystemAdapter
FILE: src/InvalidStreamProvided.php
class InvalidStreamProvided (line 9) | class InvalidStreamProvided extends BaseInvalidArgumentException impleme...
FILE: src/InvalidVisibilityProvided.php
class InvalidVisibilityProvided (line 11) | class InvalidVisibilityProvided extends InvalidArgumentException impleme...
method withVisibility (line 13) | public static function withVisibility(string $visibility, string $expe...
FILE: src/Local/FallbackMimeTypeDetector.php
class FallbackMimeTypeDetector (line 10) | class FallbackMimeTypeDetector implements MimeTypeDetector
method __construct (line 20) | public function __construct(
method detectMimeType (line 27) | public function detectMimeType(string $path, $contents): ?string
method detectMimeTypeFromBuffer (line 32) | public function detectMimeTypeFromBuffer(string $contents): ?string
method detectMimeTypeFromPath (line 37) | public function detectMimeTypeFromPath(string $path): ?string
method detectMimeTypeFromFile (line 42) | public function detectMimeTypeFromFile(string $path): ?string
FILE: src/Local/LocalFilesystemAdapter.php
class LocalFilesystemAdapter (line 50) | class LocalFilesystemAdapter implements FilesystemAdapter, ChecksumProvider
method __construct (line 72) | public function __construct(
method ensureRootDirectoryExists (line 95) | private function ensureRootDirectoryExists(): void
method write (line 105) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 110) | public function writeStream(string $path, $contents, Config $config): ...
method writeToFile (line 118) | private function writeToFile(string $path, $contents, Config $config):...
method delete (line 137) | public function delete(string $path): void
method deleteDirectory (line 152) | public function deleteDirectory(string $prefix): void
method listDirectoryRecursively (line 176) | private function listDirectoryRecursively(
method deleteFileInfoObject (line 190) | protected function deleteFileInfoObject(SplFileInfo $file): bool
method listContents (line 202) | public function listContents(string $path, bool $deep): iterable
method move (line 244) | public function move(string $source, string $destination, Config $conf...
method copy (line 265) | public function copy(string $source, string $destination, Config $conf...
method read (line 292) | public function read(string $path): string
method readStream (line 305) | public function readStream(string $path)
method ensureDirectoryExists (line 318) | protected function ensureDirectoryExists(string $dirname, int $visibil...
method fileExists (line 339) | public function fileExists(string $location): bool
method directoryExists (line 346) | public function directoryExists(string $location): bool
method createDirectory (line 353) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 373) | public function setVisibility(string $path, string $visibility): void
method visibility (line 383) | public function visibility(string $path): FileAttributes
method resolveDirectoryVisibility (line 400) | private function resolveDirectoryVisibility(?string $visibility): int
method mimeType (line 407) | public function mimeType(string $path): FileAttributes
method lastModified (line 425) | public function lastModified(string $path): FileAttributes
method fileSize (line 439) | public function fileSize(string $path): FileAttributes
method checksum (line 452) | public function checksum(string $path, Config $config): string
method listDirectory (line 466) | private function listDirectory(string $location): Generator
method setPermissions (line 479) | private function setPermissions(string $location, int $visibility): void
FILE: src/Local/LocalFilesystemAdapterTest.php
class LocalFilesystemAdapterTest (line 43) | class LocalFilesystemAdapterTest extends FilesystemAdapterTestCase
method setUp (line 47) | protected function setUp(): void
method tearDown (line 53) | protected function tearDown(): void
method creating_a_local_filesystem_creates_a_root_directory (line 62) | public function creating_a_local_filesystem_creates_a_root_directory()...
method creating_a_local_filesystem_does_not_create_a_root_directory_when_constructed_with_lazy_root_creation (line 71) | public function creating_a_local_filesystem_does_not_create_a_root_dir...
method not_being_able_to_create_a_root_directory_results_in_an_exception (line 80) | public function not_being_able_to_create_a_root_directory_results_in_a...
method falling_back_to_extension_lookup_when_finding_mime_type_of_empty_file (line 91) | public function falling_back_to_extension_lookup_when_finding_mime_typ...
method writing_a_file (line 103) | public function writing_a_file(): void
method writing_a_file_with_a_stream (line 117) | public function writing_a_file_with_a_stream(): void
method deleting_a_file_during_contents_listing (line 135) | public function deleting_a_file_during_contents_listing(): void
method writing_a_file_with_a_stream_and_visibility (line 182) | public function writing_a_file_with_a_stream_and_visibility(): void
method writing_a_file_with_visibility (line 197) | public function writing_a_file_with_visibility(): void
method failing_to_set_visibility (line 208) | public function failing_to_set_visibility(): void
method failing_to_write_a_file (line 218) | public function failing_to_write_a_file(): void
method failing_to_write_a_file_using_a_stream (line 227) | public function failing_to_write_a_file_using_a_stream(): void
method deleting_a_file (line 241) | public function deleting_a_file(): void
method deleting_a_file_that_does_not_exist (line 252) | public function deleting_a_file_that_does_not_exist(): void
method deleting_a_file_that_cannot_be_deleted (line 262) | public function deleting_a_file_that_cannot_be_deleted(): void
method checking_if_a_file_exists (line 275) | public function checking_if_a_file_exists(): void
method checking_if_a_file_exists_that_does_not_exsist (line 286) | public function checking_if_a_file_exists_that_does_not_exsist(): void
method listing_contents (line 296) | public function listing_contents(): void
method listing_contents_recursively (line 312) | public function listing_contents_recursively(): void
method listing_a_non_existing_directory (line 328) | public function listing_a_non_existing_directory(): void
method listing_directory_contents_with_link_skipping (line 341) | public function listing_directory_contents_with_link_skipping(): void
method listing_directory_contents_with_disallowing_links (line 357) | public function listing_directory_contents_with_disallowing_links(): void
method retrieving_visibility_while_listing_directory_contents (line 372) | public function retrieving_visibility_while_listing_directory_contents...
method deleting_a_directory (line 403) | public function deleting_a_directory(): void
method deleting_directories_with_other_directories_in_it (line 419) | public function deleting_directories_with_other_directories_in_it(): void
method deleting_a_non_existing_directory (line 431) | public function deleting_a_non_existing_directory(): void
method not_being_able_to_delete_a_directory (line 441) | public function not_being_able_to_delete_a_directory(): void
method not_being_able_to_delete_a_sub_directory (line 455) | public function not_being_able_to_delete_a_sub_directory(): void
method creating_a_directory (line 469) | public function creating_a_directory(): void
method not_being_able_to_create_a_directory (line 488) | public function not_being_able_to_create_a_directory(): void
method creating_a_directory_is_idempotent (line 498) | public function creating_a_directory_is_idempotent(): void
method retrieving_visibility (line 510) | public function retrieving_visibility(): void
method not_being_able_to_retrieve_visibility (line 522) | public function not_being_able_to_retrieve_visibility(): void
method moving_a_file (line 532) | public function moving_a_file(): void
method moving_a_file_with_visibility (line 545) | public function moving_a_file_with_visibility(): void
method not_being_able_to_move_a_file (line 559) | public function not_being_able_to_move_a_file(): void
method copying_a_file (line 569) | public function copying_a_file(): void
method copying_a_file_with_visibility (line 581) | public function copying_a_file_with_visibility(): void
method copying_a_file_retaining_visibility (line 595) | public function copying_a_file_retaining_visibility(): void
method not_being_able_to_copy_a_file (line 612) | public function not_being_able_to_copy_a_file(): void
method getting_mimetype (line 622) | public function getting_mimetype(): void
method failing_to_get_the_mimetype (line 636) | public function failing_to_get_the_mimetype(): void
method allowing_inconclusive_mime_type (line 653) | public function allowing_inconclusive_mime_type(): void
method fetching_unknown_mime_type_of_a_file (line 671) | public function fetching_unknown_mime_type_of_a_file(): void
method not_being_able_to_get_mimetype (line 681) | public function not_being_able_to_get_mimetype(): void
method getting_last_modified (line 694) | public function getting_last_modified(): void
method not_being_able_to_get_last_modified (line 706) | public function not_being_able_to_get_last_modified(): void
method getting_file_size (line 716) | public function getting_file_size(): void
method not_being_able_to_get_file_size (line 727) | public function not_being_able_to_get_file_size(): void
method reading_a_file (line 737) | public function reading_a_file(): void
method not_being_able_to_read_a_file (line 748) | public function not_being_able_to_read_a_file(): void
method reading_a_stream (line 758) | public function reading_a_stream(): void
method not_being_able_to_stream_read_a_file (line 772) | public function not_being_able_to_stream_read_a_file(): void
method assertFileHasPermissions (line 787) | private function assertFileHasPermissions(string $file, int $expectedP...
method assertFileContains (line 798) | private function assertFileContains(string $file, string $expectedCont...
method createFilesystemAdapter (line 805) | protected static function createFilesystemAdapter(): FilesystemAdapter
method get_checksum_with_specified_algo (line 813) | public function get_checksum_with_specified_algo(): void
FILE: src/MountManager.php
class MountManager (line 14) | class MountManager implements FilesystemOperator
method __construct (line 31) | public function __construct(array $filesystems = [], array $config = [])
method dangerouslyMountFilesystems (line 41) | public function dangerouslyMountFilesystems(string $key, FilesystemOpe...
method extend (line 49) | public function extend(array $filesystems, array $config = []): MountM...
method fileExists (line 58) | public function fileExists(string $location): bool
method has (line 70) | public function has(string $location): bool
method directoryExists (line 82) | public function directoryExists(string $location): bool
method read (line 94) | public function read(string $location): string
method readStream (line 106) | public function readStream(string $location)
method listContents (line 118) | public function listContents(string $location, bool $deep = self::LIST...
method lastModified (line 133) | public function lastModified(string $location): int
method fileSize (line 145) | public function fileSize(string $location): int
method mimeType (line 157) | public function mimeType(string $location): string
method visibility (line 169) | public function visibility(string $path): string
method write (line 181) | public function write(string $location, string $contents, array $confi...
method writeStream (line 193) | public function writeStream(string $location, $contents, array $config...
method setVisibility (line 200) | public function setVisibility(string $path, string $visibility): void
method delete (line 207) | public function delete(string $location): void
method deleteDirectory (line 219) | public function deleteDirectory(string $location): void
method createDirectory (line 231) | public function createDirectory(string $location, array $config = []):...
method move (line 243) | public function move(string $source, string $destination, array $confi...
method copy (line 260) | public function copy(string $source, string $destination, array $confi...
method publicUrl (line 285) | public function publicUrl(string $path, array $config = []): string
method temporaryUrl (line 297) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
method checksum (line 309) | public function checksum(string $path, array $config = []): string
method mountFilesystems (line 321) | private function mountFilesystems(array $filesystems): void
method guardAgainstInvalidMount (line 331) | private function guardAgainstInvalidMount(mixed $key, mixed $filesyste...
method mountFilesystem (line 342) | private function mountFilesystem(string $key, FilesystemOperator $file...
method determineFilesystemAndPath (line 352) | private function determineFilesystemAndPath(string $path): array
method copyInSameFilesystem (line 369) | private function copyInSameFilesystem(
method copyAcrossFilesystem (line 384) | private function copyAcrossFilesystem(
method moveInTheSameFilesystem (line 410) | private function moveInTheSameFilesystem(
method moveAcrossFilesystems (line 425) | private function moveAcrossFilesystems(string $source, string $destina...
FILE: src/MountManagerTest.php
class MountManagerTest (line 17) | class MountManagerTest extends TestCase
method setUp (line 44) | protected function setUp(): void
method copying_without_retaining_visibility (line 60) | public function copying_without_retaining_visibility(): void
method extending_without_new_mounts_is_equal_but_not_the_same (line 82) | public function extending_without_new_mounts_is_equal_but_not_the_same...
method extending_with_new_mounts_is_not_equal (line 93) | public function extending_with_new_mounts_is_not_equal(): void
method extending_exposes_a_usable_mount_on_the_extension (line 105) | public function extending_exposes_a_usable_mount_on_the_extension(): void
method extending_does_not_mount_on_the_original_mount_manager (line 120) | public function extending_does_not_mount_on_the_original_mount_manager...
method copying_while_retaining_visibility (line 134) | public function copying_while_retaining_visibility(): void
method writing_a_file (line 156) | public function writing_a_file(): void
method writing_a_file_with_a_stream (line 171) | public function writing_a_file_with_a_stream(): void
method not_being_able_to_write_a_file (line 183) | public function not_being_able_to_write_a_file(): void
method not_being_able_to_stream_write_a_file (line 195) | public function not_being_able_to_stream_write_a_file(): void
method failing_a_one_param_method (line 216) | public function failing_a_one_param_method(string $method, FilesystemO...
method dpMetadataRetrieverMethods (line 225) | public static function dpMetadataRetrieverMethods(): iterable
method reading_a_file (line 242) | public function reading_a_file(): void
method reading_a_file_as_a_stream (line 254) | public function reading_a_file_as_a_stream(): void
method checking_existence_for_an_existing_file (line 268) | public function checking_existence_for_an_existing_file(): void
method checking_existence_for_an_non_existing_file (line 280) | public function checking_existence_for_an_non_existing_file(): void
method checking_existence_for_an_non_existing_directory (line 290) | public function checking_existence_for_an_non_existing_directory(): void
method checking_existence_for_an_existing_directory (line 300) | public function checking_existence_for_an_existing_directory(): void
method checking_existence_for_an_existing_file_using_has (line 312) | public function checking_existence_for_an_existing_file_using_has(): void
method checking_existence_for_an_non_existing_file_using_has (line 324) | public function checking_existence_for_an_non_existing_file_using_has(...
method checking_existence_for_an_non_existing_directory_using_has (line 334) | public function checking_existence_for_an_non_existing_directory_using...
method checking_existence_for_an_existing_directory_using_has (line 344) | public function checking_existence_for_an_existing_directory_using_has...
method deleting_a_file (line 356) | public function deleting_a_file(): void
method deleting_a_directory (line 368) | public function deleting_a_directory(): void
method setting_visibility (line 380) | public function setting_visibility(): void
method retrieving_metadata (line 393) | public function retrieving_metadata(): void
method creating_a_directory (line 410) | public function creating_a_directory(): void
method list_directory (line 427) | public function list_directory(): void
method copying_in_the_same_filesystem (line 450) | public function copying_in_the_same_filesystem(): void
method failing_to_copy_in_the_same_filesystem (line 464) | public function failing_to_copy_in_the_same_filesystem(): void
method failing_to_move_in_the_same_filesystem (line 477) | public function failing_to_move_in_the_same_filesystem(): void
method moving_in_the_same_filesystem (line 490) | public function moving_in_the_same_filesystem(): void
method moving_across_filesystem (line 504) | public function moving_across_filesystem(): void
method failing_to_move_across_filesystem (line 518) | public function failing_to_move_across_filesystem(): void
method failing_to_copy_across_filesystem (line 532) | public function failing_to_copy_across_filesystem(): void
method listing_contents (line 546) | public function listing_contents(): void
method dangerously_mounting_additional_filesystems (line 560) | public function dangerously_mounting_additional_filesystems(): void
method guarding_against_valid_mount_identifiers (line 572) | public function guarding_against_valid_mount_identifiers(): void
method guarding_against_mounting_invalid_filesystems (line 583) | public function guarding_against_mounting_invalid_filesystems(): void
method guarding_against_using_paths_without_mount_prefix (line 594) | public function guarding_against_using_paths_without_mount_prefix(): void
method guard_against_using_unknown_mount (line 604) | public function guard_against_using_unknown_mount(): void
method generate_public_url (line 614) | public function generate_public_url(): void
method provide_checksum (line 631) | public function provide_checksum(): void
FILE: src/PathNormalizer.php
type PathNormalizer (line 7) | interface PathNormalizer
method normalizePath (line 9) | public function normalizePath(string $path): string;
FILE: src/PathPrefixer.php
class PathPrefixer (line 11) | final class PathPrefixer
method __construct (line 15) | public function __construct(string $prefix, private string $separator ...
method prefixPath (line 24) | public function prefixPath(string $path): string
method stripPrefix (line 29) | public function stripPrefix(string $path): string
method stripDirectoryPrefix (line 35) | public function stripDirectoryPrefix(string $path): string
method prefixDirectoryPath (line 40) | public function prefixDirectoryPath(string $path): string
FILE: src/PathPrefixerTest.php
class PathPrefixerTest (line 9) | class PathPrefixerTest extends TestCase
method path_prefixing_with_a_prefix (line 14) | public function path_prefixing_with_a_prefix(): void
method path_stripping_with_a_prefix (line 24) | public function path_stripping_with_a_prefix(): void
method an_absolute_root_path_is_supported (line 36) | public function an_absolute_root_path_is_supported(string $rootPath, s...
method dpRootPaths (line 43) | public static function dpRootPaths(): iterable
method path_stripping_is_reversable (line 52) | public function path_stripping_is_reversable(): void
method prefixing_without_a_prefix (line 64) | public function prefixing_without_a_prefix(): void
method prefixing_for_a_directory (line 78) | public function prefixing_for_a_directory(): void
method prefixing_for_a_directory_without_a_prefix (line 91) | public function prefixing_for_a_directory_without_a_prefix(): void
method stripping_a_directory_prefix (line 104) | public function stripping_a_directory_prefix(): void
FILE: src/PathPrefixing/PathPrefixedAdapter.php
class PathPrefixedAdapter (line 30) | class PathPrefixedAdapter implements FilesystemAdapter, PublicUrlGenerat...
method __construct (line 36) | public function __construct(private FilesystemAdapter $adapter, string...
method read (line 45) | public function read(string $location): string
method readStream (line 54) | public function readStream(string $location)
method listContents (line 63) | public function listContents(string $location, bool $deep): Generator
method fileExists (line 70) | public function fileExists(string $location): bool
method directoryExists (line 79) | public function directoryExists(string $location): bool
method lastModified (line 88) | public function lastModified(string $path): FileAttributes
method fileSize (line 97) | public function fileSize(string $path): FileAttributes
method mimeType (line 106) | public function mimeType(string $path): FileAttributes
method visibility (line 115) | public function visibility(string $path): FileAttributes
method write (line 124) | public function write(string $location, string $contents, Config $conf...
method writeStream (line 133) | public function writeStream(string $location, $contents, Config $confi...
method setVisibility (line 142) | public function setVisibility(string $path, string $visibility): void
method delete (line 151) | public function delete(string $location): void
method deleteDirectory (line 160) | public function deleteDirectory(string $location): void
method createDirectory (line 169) | public function createDirectory(string $location, Config $config): void
method move (line 178) | public function move(string $source, string $destination, Config $conf...
method copy (line 187) | public function copy(string $source, string $destination, Config $conf...
method publicUrl (line 196) | public function publicUrl(string $path, Config $config): string
method checksum (line 205) | public function checksum(string $path, Config $config): string
method temporaryUrl (line 214) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/PathPrefixing/PathPrefixedAdapterTest.php
class PathPrefixedAdapterTest (line 15) | class PathPrefixedAdapterTest extends TestCase
method testPrefix (line 17) | public function testPrefix(): void
method testWriteStream (line 59) | public function testWriteStream(): void
method testEmptyPrefix (line 75) | public function testEmptyPrefix(): void
method generating_a_public_url (line 84) | public function generating_a_public_url(): void
method calculate_checksum_using_decorated_adapter (line 102) | public function calculate_checksum_using_decorated_adapter(): void
method calculate_checksum_using_current_adapter (line 120) | public function calculate_checksum_using_current_adapter(): void
method failing_to_generate_a_public_url (line 133) | public function failing_to_generate_a_public_url(): void
FILE: src/PathTraversalDetected.php
class PathTraversalDetected (line 9) | class PathTraversalDetected extends RuntimeException implements Filesyst...
method path (line 13) | public function path(): string
method forPath (line 18) | public static function forPath(string $path): PathTraversalDetected
FILE: src/PhpseclibV2/ConnectionProvider.php
type ConnectionProvider (line 12) | interface ConnectionProvider
method provideConnection (line 14) | public function provideConnection(): SFTP;
FILE: src/PhpseclibV2/ConnectivityChecker.php
type ConnectivityChecker (line 12) | interface ConnectivityChecker
method isConnected (line 14) | public function isConnected(SFTP $connection): bool;
FILE: src/PhpseclibV2/FixatedConnectivityChecker.php
class FixatedConnectivityChecker (line 12) | class FixatedConnectivityChecker implements ConnectivityChecker
method __construct (line 24) | public function __construct(int $succeedAfter = 0)
method isConnected (line 29) | public function isConnected(SFTP $connection): bool
FILE: src/PhpseclibV2/SftpAdapter.php
class SftpAdapter (line 35) | class SftpAdapter implements FilesystemAdapter
method __construct (line 57) | public function __construct(
method fileExists (line 70) | public function fileExists(string $path): bool
method directoryExists (line 81) | public function directoryExists(string $path): bool
method upload (line 99) | private function upload(string $path, $contents, Config $config): void
method ensureParentDirectoryExists (line 114) | private function ensureParentDirectoryExists(string $path, Config $con...
method makeDirectory (line 127) | private function makeDirectory(string $directory, ?string $visibility)...
method write (line 145) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 156) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 167) | public function read(string $path): string
method readStream (line 180) | public function readStream(string $path)
method delete (line 197) | public function delete(string $path): void
method deleteDirectory (line 204) | public function deleteDirectory(string $path): void
method createDirectory (line 212) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 217) | public function setVisibility(string $path, string $visibility): void
method fetchFileMetadata (line 228) | private function fetchFileMetadata(string $path, string $type): FileAt...
method mimeType (line 247) | public function mimeType(string $path): FileAttributes
method lastModified (line 264) | public function lastModified(string $path): FileAttributes
method fileSize (line 269) | public function fileSize(string $path): FileAttributes
method visibility (line 274) | public function visibility(string $path): FileAttributes
method listContents (line 279) | public function listContents(string $path, bool $deep): iterable
method convertListingToAttributes (line 308) | private function convertListingToAttributes(string $path, array $attri...
method move (line 329) | public function move(string $source, string $destination, Config $conf...
method copy (line 346) | public function copy(string $source, string $destination, Config $conf...
FILE: src/PhpseclibV2/SftpAdapterTest.php
class SftpAdapterTest (line 22) | class SftpAdapterTest extends FilesystemAdapterTestCase
method setUpBeforeClass (line 34) | public static function setUpBeforeClass(): void
method createFilesystemAdapter (line 41) | protected static function createFilesystemAdapter(): FilesystemAdapter
method setupConnectionProvider (line 52) | public function setupConnectionProvider(): void
method failing_to_create_a_directory (line 63) | public function failing_to_create_a_directory(): void
method failing_to_write_a_file (line 75) | public function failing_to_write_a_file(): void
method failing_to_read_a_file (line 87) | public function failing_to_read_a_file(): void
method failing_to_read_a_file_as_a_stream (line 99) | public function failing_to_read_a_file_as_a_stream(): void
method failing_to_write_a_file_using_streams (line 111) | public function failing_to_write_a_file_using_streams(): void
method detecting_mimetype (line 128) | public function detecting_mimetype(): void
method failing_to_chmod_when_writing (line 141) | public function failing_to_chmod_when_writing(): void
method failing_to_move_a_file_cause_the_parent_directory_cant_be_created (line 154) | public function failing_to_move_a_file_cause_the_parent_directory_cant...
method failing_to_copy_a_file (line 166) | public function failing_to_copy_a_file(): void
method failing_to_copy_a_file_because_writing_fails (line 178) | public function failing_to_copy_a_file_because_writing_fails(): void
method failing_to_chmod_when_writing_with_a_stream (line 192) | public function failing_to_chmod_when_writing_with_a_stream(): void
method list_contents_directory_does_not_exist (line 210) | public function list_contents_directory_does_not_exist(): void
method connectionProvider (line 216) | private static function connectionProvider(): ConnectionProvider
method adapterWithInvalidRoot (line 228) | private function adapterWithInvalidRoot(): SftpAdapter
FILE: src/PhpseclibV2/SftpConnectionProvider.php
class SftpConnectionProvider (line 15) | class SftpConnectionProvider implements ConnectionProvider
method __construct (line 77) | public function __construct(
method provideConnection (line 104) | public function provideConnection(): SFTP
method setupConnection (line 128) | private function setupConnection(): SFTP
method checkFingerprint (line 144) | private function checkFingerprint(SFTP $connection): void
method getFingerprintFromPublicKey (line 163) | private function getFingerprintFromPublicKey(string $publicKey): string
method authenticate (line 170) | private function authenticate(SFTP $connection): void
method fromArray (line 181) | public static function fromArray(array $options): SftpConnectionProvider
method authenticateWithPrivateKey (line 198) | private function authenticateWithPrivateKey(SFTP $connection): void
method loadPrivateKey (line 213) | private function loadPrivateKey(): RSA
method authenticateWithAgent (line 232) | private function authenticateWithAgent(SFTP $connection): void
FILE: src/PhpseclibV2/SftpConnectionProviderTest.php
class SftpConnectionProviderTest (line 17) | class SftpConnectionProviderTest extends TestCase
method setUp (line 19) | protected function setUp(): void
method giving_up_after_5_connection_failures (line 31) | public function giving_up_after_5_connection_failures(): void
method trying_until_5_tries (line 52) | public function trying_until_5_tries(): void
method authenticating_with_a_private_key (line 72) | public function authenticating_with_a_private_key(): void
method authenticating_with_an_invalid_private_key (line 91) | public function authenticating_with_an_invalid_private_key(): void
method authenticating_with_an_ssh_agent (line 110) | public function authenticating_with_an_ssh_agent(): void
method failing_to_authenticating_with_an_ssh_agent (line 128) | public function failing_to_authenticating_with_an_ssh_agent(): void
method authenticating_with_a_private_key_and_falling_back_to_password (line 147) | public function authenticating_with_a_private_key_and_falling_back_to_...
method not_being_able_to_authenticate_with_a_private_key (line 167) | public function not_being_able_to_authenticate_with_a_private_key(): void
method verifying_a_fingerprint (line 186) | public function verifying_a_fingerprint(): void
method providing_an_invalid_fingerprint (line 208) | public function providing_an_invalid_fingerprint(): void
method providing_an_invalid_password (line 227) | public function providing_an_invalid_password(): void
method computeFingerPrint (line 241) | private function computeFingerPrint(string $publicKey): string
FILE: src/PhpseclibV2/SftpStub.php
class SftpStub (line 14) | class SftpStub extends SFTP
method failOnChmod (line 21) | public function failOnChmod(string $filename): void
method chmod (line 34) | public function chmod($mode, $filename, $recursive = false)
method failOnPut (line 48) | public function failOnPut(string $filename): void
method put (line 64) | public function put(
method formatTripKey (line 87) | private function formatTripKey(...$arguments): string
method reset (line 98) | public function reset(): void
FILE: src/PhpseclibV2/SimpleConnectivityChecker.php
class SimpleConnectivityChecker (line 12) | class SimpleConnectivityChecker implements ConnectivityChecker
method isConnected (line 14) | public function isConnected(SFTP $connection): bool
FILE: src/PhpseclibV2/StubSftpConnectionProvider.php
class StubSftpConnectionProvider (line 12) | class StubSftpConnectionProvider implements ConnectionProvider
method __construct (line 39) | public function __construct(
method provideConnection (line 51) | public function provideConnection(): SFTP
FILE: src/PhpseclibV2/UnableToAuthenticate.php
class UnableToAuthenticate (line 13) | class UnableToAuthenticate extends RuntimeException implements Filesyste...
method withPassword (line 15) | public static function withPassword(): UnableToAuthenticate
method withPrivateKey (line 20) | public static function withPrivateKey(): UnableToAuthenticate
method withSshAgent (line 25) | public static function withSshAgent(): UnableToAuthenticate
FILE: src/PhpseclibV2/UnableToConnectToSftpHost.php
class UnableToConnectToSftpHost (line 13) | class UnableToConnectToSftpHost extends RuntimeException implements File...
method atHostname (line 15) | public static function atHostname(string $host): UnableToConnectToSftp...
FILE: src/PhpseclibV2/UnableToEstablishAuthenticityOfHost.php
class UnableToEstablishAuthenticityOfHost (line 13) | class UnableToEstablishAuthenticityOfHost extends RuntimeException imple...
method becauseTheAuthenticityCantBeEstablished (line 15) | public static function becauseTheAuthenticityCantBeEstablished(string ...
FILE: src/PhpseclibV2/UnableToLoadPrivateKey.php
class UnableToLoadPrivateKey (line 13) | class UnableToLoadPrivateKey extends RuntimeException implements Filesys...
method __construct (line 15) | public function __construct(string $message = "Unable to load private ...
FILE: src/PhpseclibV3/ConnectionProvider.php
type ConnectionProvider (line 12) | interface ConnectionProvider
method provideConnection (line 14) | public function provideConnection(): SFTP;
FILE: src/PhpseclibV3/ConnectivityChecker.php
type ConnectivityChecker (line 9) | interface ConnectivityChecker
method isConnected (line 11) | public function isConnected(SFTP $connection): bool;
FILE: src/PhpseclibV3/FixatedConnectivityChecker.php
class FixatedConnectivityChecker (line 9) | class FixatedConnectivityChecker implements ConnectivityChecker
method __construct (line 21) | public function __construct(int $succeedAfter = 0)
method isConnected (line 26) | public function isConnected(SFTP $connection): bool
FILE: src/PhpseclibV3/SftpAdapter.php
class SftpAdapter (line 32) | class SftpAdapter implements FilesystemAdapter
method __construct (line 38) | public function __construct(
method fileExists (line 51) | public function fileExists(string $path): bool
method disconnect (line 62) | public function disconnect(): void
method directoryExists (line 67) | public function directoryExists(string $path): bool
method upload (line 85) | private function upload(string $path, $contents, Config $config): void
method ensureParentDirectoryExists (line 100) | private function ensureParentDirectoryExists(string $path, Config $con...
method makeDirectory (line 113) | private function makeDirectory(string $directory, ?string $visibility)...
method write (line 131) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 142) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 153) | public function read(string $path): string
method readStream (line 166) | public function readStream(string $path)
method delete (line 183) | public function delete(string $path): void
method deleteDirectory (line 190) | public function deleteDirectory(string $path): void
method createDirectory (line 198) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 203) | public function setVisibility(string $path, string $visibility): void
method fetchFileMetadata (line 214) | private function fetchFileMetadata(string $path, string $type): FileAt...
method mimeType (line 233) | public function mimeType(string $path): FileAttributes
method lastModified (line 250) | public function lastModified(string $path): FileAttributes
method fileSize (line 255) | public function fileSize(string $path): FileAttributes
method visibility (line 260) | public function visibility(string $path): FileAttributes
method listContents (line 265) | public function listContents(string $path, bool $deep): iterable
method convertListingToAttributes (line 294) | private function convertListingToAttributes(string $path, array $attri...
method move (line 315) | public function move(string $source, string $destination, Config $conf...
method copy (line 346) | public function copy(string $source, string $destination, Config $conf...
method __destruct (line 365) | public function __destruct()
FILE: src/PhpseclibV3/SftpAdapterTest.php
class SftpAdapterTest (line 24) | class SftpAdapterTest extends FilesystemAdapterTestCase
method setUpBeforeClass (line 26) | public static function setUpBeforeClass(): void
method createFilesystemAdapter (line 43) | protected static function createFilesystemAdapter(): FilesystemAdapter
method setupConnectionProvider (line 54) | public function setupConnectionProvider(): void
method failing_to_create_a_directory (line 65) | public function failing_to_create_a_directory(): void
method failing_to_write_a_file (line 77) | public function failing_to_write_a_file(): void
method failing_to_read_a_file (line 89) | public function failing_to_read_a_file(): void
method failing_to_read_a_file_as_a_stream (line 101) | public function failing_to_read_a_file_as_a_stream(): void
method failing_to_write_a_file_using_streams (line 113) | public function failing_to_write_a_file_using_streams(): void
method detecting_mimetype (line 130) | public function detecting_mimetype(): void
method failing_to_chmod_when_writing (line 143) | public function failing_to_chmod_when_writing(): void
method failing_to_move_a_file_cause_the_parent_directory_cant_be_created (line 156) | public function failing_to_move_a_file_cause_the_parent_directory_cant...
method failing_to_copy_a_file (line 168) | public function failing_to_copy_a_file(): void
method failing_to_copy_a_file_because_writing_fails (line 180) | public function failing_to_copy_a_file_because_writing_fails(): void
method failing_to_chmod_when_writing_with_a_stream (line 194) | public function failing_to_chmod_when_writing_with_a_stream(): void
method list_contents_directory_does_not_exist (line 212) | public function list_contents_directory_does_not_exist(): void
method it_can_proactively_close_a_connection (line 221) | public function it_can_proactively_close_a_connection(): void
method moving_a_file_and_overwriting (line 238) | public function moving_a_file_and_overwriting(): void
method connectionProvider (line 266) | private static function connectionProvider(): StubSftpConnectionProvider
method adapterWithInvalidRoot (line 278) | private function adapterWithInvalidRoot(): SftpAdapter
FILE: src/PhpseclibV3/SftpConnectionProvider.php
class SftpConnectionProvider (line 19) | class SftpConnectionProvider implements ConnectionProvider
method __construct (line 32) | public function __construct(
method provideConnection (line 50) | public function provideConnection(): SFTP
method disconnect (line 86) | public function disconnect(): void
method setupConnection (line 94) | private function setupConnection(): SFTP
method checkFingerprint (line 111) | private function checkFingerprint(SFTP $connection): void
method getFingerprintFromPublicKey (line 130) | private function getFingerprintFromPublicKey(string $publicKey): string
method authenticate (line 138) | private function authenticate(SFTP $connection): void
method authenticateWithUsernameAndPassword (line 149) | private function authenticateWithUsernameAndPassword(SFTP $connection)...
method fromArray (line 156) | public static function fromArray(array $options): SftpConnectionProvider
method authenticateWithPrivateKey (line 174) | private function authenticateWithPrivateKey(SFTP $connection): void
method loadPrivateKey (line 189) | private function loadPrivateKey(): AsymmetricKey
method authenticateWithAgent (line 206) | private function authenticateWithAgent(SFTP $connection): void
FILE: src/PhpseclibV3/SftpConnectionProviderTest.php
class SftpConnectionProviderTest (line 26) | class SftpConnectionProviderTest extends TestCase
method setUpBeforeClass (line 30) | public static function setUpBeforeClass(): void
method giving_up_after_5_connection_failures (line 40) | public function giving_up_after_5_connection_failures(): void
method trying_until_5_tries (line 61) | public function trying_until_5_tries(): void
method authenticating_with_a_private_key (line 81) | public function authenticating_with_a_private_key(): void
method authenticating_with_an_invalid_private_key (line 101) | public function authenticating_with_an_invalid_private_key(): void
method authenticating_with_an_ssh_agent (line 120) | public function authenticating_with_an_ssh_agent(): void
method failing_to_authenticating_with_an_ssh_agent (line 145) | public function failing_to_authenticating_with_an_ssh_agent(): void
method authenticating_with_a_private_key_and_falling_back_to_password (line 164) | public function authenticating_with_a_private_key_and_falling_back_to_...
method not_being_able_to_authenticate_with_a_private_key (line 187) | public function not_being_able_to_authenticate_with_a_private_key(): void
method verifying_a_fingerprint (line 206) | public function verifying_a_fingerprint(): void
method providing_an_invalid_fingerprint (line 231) | public function providing_an_invalid_fingerprint(): void
method providing_an_invalid_password (line 250) | public function providing_an_invalid_password(): void
method retries_several_times_until_failure (line 269) | public function retries_several_times_until_failure(): void
method authenticate_with_supported_preferred_kex_algorithm_succeeds (line 310) | public function authenticate_with_supported_preferred_kex_algorithm_su...
method authenticate_with_unsupported_preferred_kex_algorithm_failes (line 344) | public function authenticate_with_unsupported_preferred_kex_algorithm_...
method computeFingerPrint (line 363) | private function computeFingerPrint(string $publicKey): string
method runWithRetries (line 376) | public function runWithRetries(callable $scenario, ?string $expected =...
FILE: src/PhpseclibV3/SftpStub.php
class SftpStub (line 12) | class SftpStub extends SFTP
method failOnChmod (line 19) | public function failOnChmod(string $filename): void
method chmod (line 32) | public function chmod($mode, $filename, $recursive = false)
method failOnPut (line 46) | public function failOnPut(string $filename): void
method put (line 62) | public function put(
method formatTripKey (line 85) | private function formatTripKey(...$arguments): string
method resetTripWires (line 96) | public function resetTripWires(): void
FILE: src/PhpseclibV3/SimpleConnectivityChecker.php
class SimpleConnectivityChecker (line 10) | class SimpleConnectivityChecker implements ConnectivityChecker
method __construct (line 12) | public function __construct(
method create (line 17) | public static function create(): SimpleConnectivityChecker
method withUsingPing (line 22) | public function withUsingPing(bool $usePing): SimpleConnectivityChecker
method isConnected (line 30) | public function isConnected(SFTP $connection): bool
FILE: src/PhpseclibV3/StubSftpConnectionProvider.php
class StubSftpConnectionProvider (line 9) | class StubSftpConnectionProvider implements ConnectionProvider
method __construct (line 16) | public function __construct(
method disconnect (line 24) | public function disconnect(): void
method provideConnection (line 31) | public function provideConnection(): SFTP
FILE: src/PhpseclibV3/UnableToAuthenticate.php
class UnableToAuthenticate (line 10) | class UnableToAuthenticate extends RuntimeException implements Filesyste...
method __construct (line 14) | public function __construct(string $message, ?string $lastError = null)
method withPassword (line 20) | public static function withPassword(?string $lastError = null): Unable...
method withPrivateKey (line 25) | public static function withPrivateKey(?string $lastError = null): Unab...
method withSshAgent (line 30) | public static function withSshAgent(?string $lastError = null): Unable...
method connectionError (line 35) | public function connectionError(): ?string
FILE: src/PhpseclibV3/UnableToConnectToSftpHost.php
class UnableToConnectToSftpHost (line 11) | class UnableToConnectToSftpHost extends RuntimeException implements File...
method atHostname (line 13) | public static function atHostname(string $host, ?Throwable $previous =...
FILE: src/PhpseclibV3/UnableToEstablishAuthenticityOfHost.php
class UnableToEstablishAuthenticityOfHost (line 10) | class UnableToEstablishAuthenticityOfHost extends RuntimeException imple...
method becauseTheAuthenticityCantBeEstablished (line 12) | public static function becauseTheAuthenticityCantBeEstablished(string ...
FILE: src/PhpseclibV3/UnableToLoadPrivateKey.php
class UnableToLoadPrivateKey (line 11) | class UnableToLoadPrivateKey extends RuntimeException implements Filesys...
method __construct (line 13) | public function __construct(?string $message = 'Unable to load private...
FILE: src/PortableVisibilityGuard.php
class PortableVisibilityGuard (line 7) | final class PortableVisibilityGuard
method guardAgainstInvalidInput (line 9) | public static function guardAgainstInvalidInput(string $visibility): void
FILE: src/ProxyArrayAccessToProperties.php
type ProxyArrayAccessToProperties (line 12) | trait ProxyArrayAccessToProperties
method formatPropertyName (line 14) | private function formatPropertyName(string $offset): string
method offsetExists (line 24) | public function offsetExists($offset): bool
method offsetGet (line 36) | #[\ReturnTypeWillChange]
method offsetSet (line 48) | #[\ReturnTypeWillChange]
method offsetUnset (line 57) | #[\ReturnTypeWillChange]
FILE: src/ReadOnly/ReadOnlyFilesystemAdapter.php
class ReadOnlyFilesystemAdapter (line 23) | class ReadOnlyFilesystemAdapter extends DecoratedAdapter implements File...
method write (line 27) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 32) | public function writeStream(string $path, $contents, Config $config): ...
method delete (line 37) | public function delete(string $path): void
method deleteDirectory (line 42) | public function deleteDirectory(string $path): void
method createDirectory (line 47) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 52) | public function setVisibility(string $path, string $visibility): void
method move (line 57) | public function move(string $source, string $destination, Config $conf...
method copy (line 62) | public function copy(string $source, string $destination, Config $conf...
method publicUrl (line 67) | public function publicUrl(string $path, Config $config): string
method checksum (line 76) | public function checksum(string $path, Config $config): string
method temporaryUrl (line 85) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/ReadOnly/ReadOnlyFilesystemAdapterTest.php
class ReadOnlyFilesystemAdapterTest (line 21) | class ReadOnlyFilesystemAdapterTest extends TestCase
method can_perform_read_operations (line 26) | public function can_perform_read_operations(): void
method cannot_write_stream (line 47) | public function cannot_write_stream(): void
method cannot_write (line 60) | public function cannot_write(): void
method cannot_delete_file (line 72) | public function cannot_delete_file(): void
method cannot_delete_directory (line 87) | public function cannot_delete_directory(): void
method cannot_create_directory (line 102) | public function cannot_create_directory(): void
method cannot_set_visibility (line 114) | public function cannot_set_visibility(): void
method cannot_move (line 129) | public function cannot_move(): void
method cannot_copy (line 144) | public function cannot_copy(): void
method generating_a_public_url (line 159) | public function generating_a_public_url(): void
method failing_to_generate_a_public_url (line 177) | public function failing_to_generate_a_public_url(): void
method realAdapter (line 186) | private function realAdapter(): InMemoryFilesystemAdapter
FILE: src/ResolveIdenticalPathConflict.php
class ResolveIdenticalPathConflict (line 6) | class ResolveIdenticalPathConflict
FILE: src/StorageAttributes.php
type StorageAttributes (line 10) | interface StorageAttributes extends JsonSerializable, ArrayAccess
method path (line 23) | public function path(): string;
method type (line 25) | public function type(): string;
method visibility (line 27) | public function visibility(): ?string;
method lastModified (line 29) | public function lastModified(): ?int;
method fromArray (line 31) | public static function fromArray(array $attributes): StorageAttributes;
method isFile (line 33) | public function isFile(): bool;
method isDir (line 35) | public function isDir(): bool;
method withPath (line 37) | public function withPath(string $path): StorageAttributes;
method extraMetadata (line 39) | public function extraMetadata(): array;
FILE: src/SymbolicLinkEncountered.php
class SymbolicLinkEncountered (line 9) | final class SymbolicLinkEncountered extends RuntimeException implements ...
method location (line 13) | public function location(): string
method atLocation (line 18) | public static function atLocation(string $pathName): SymbolicLinkEncou...
FILE: src/UnableToCheckDirectoryExistence.php
class UnableToCheckDirectoryExistence (line 7) | class UnableToCheckDirectoryExistence extends UnableToCheckExistence
method operation (line 9) | public function operation(): string
FILE: src/UnableToCheckExistence.php
class UnableToCheckExistence (line 10) | class UnableToCheckExistence extends RuntimeException implements Filesys...
method __construct (line 12) | final public function __construct(string $message = "", int $code = 0,...
method forLocation (line 17) | public static function forLocation(string $path, ?Throwable $exception...
method operation (line 22) | public function operation(): string
FILE: src/UnableToCheckFileExistence.php
class UnableToCheckFileExistence (line 7) | class UnableToCheckFileExistence extends UnableToCheckExistence
method operation (line 9) | public function operation(): string
FILE: src/UnableToCopyFile.php
class UnableToCopyFile (line 10) | final class UnableToCopyFile extends RuntimeException implements Filesys...
method source (line 22) | public function source(): string
method destination (line 27) | public function destination(): string
method fromLocationTo (line 32) | public static function fromLocationTo(
method sourceAndDestinationAreTheSame (line 44) | public static function sourceAndDestinationAreTheSame(string $source, ...
method because (line 49) | public static function because(string $reason, string $sourcePath, str...
method operation (line 58) | public function operation(): string
FILE: src/UnableToCreateDirectory.php
class UnableToCreateDirectory (line 10) | final class UnableToCreateDirectory extends RuntimeException implements ...
method atLocation (line 15) | public static function atLocation(string $dirname, string $errorMessag...
method dueToFailure (line 25) | public static function dueToFailure(string $dirname, Throwable $previo...
method operation (line 36) | public function operation(): string
method reason (line 41) | public function reason(): string
method location (line 46) | public function location(): string
FILE: src/UnableToDeleteDirectory.php
class UnableToDeleteDirectory (line 10) | final class UnableToDeleteDirectory extends RuntimeException implements ...
method atLocation (line 22) | public static function atLocation(
method operation (line 34) | public function operation(): string
method reason (line 39) | public function reason(): string
method location (line 44) | public function location(): string
FILE: src/UnableToDeleteFile.php
class UnableToDeleteFile (line 10) | final class UnableToDeleteFile extends RuntimeException implements Files...
method atLocation (line 22) | public static function atLocation(string $location, string $reason = '...
method operation (line 31) | public function operation(): string
method reason (line 36) | public function reason(): string
method location (line 41) | public function location(): string
FILE: src/UnableToGeneratePublicUrl.php
class UnableToGeneratePublicUrl (line 10) | final class UnableToGeneratePublicUrl extends RuntimeException implement...
method __construct (line 12) | public function __construct(string $reason, string $path, ?Throwable $...
method dueToError (line 17) | public static function dueToError(string $path, Throwable $exception):...
method noGeneratorConfigured (line 22) | public static function noGeneratorConfigured(string $path, string $ext...
FILE: src/UnableToGenerateTemporaryUrl.php
class UnableToGenerateTemporaryUrl (line 10) | final class UnableToGenerateTemporaryUrl extends RuntimeException implem...
method __construct (line 12) | public function __construct(string $reason, string $path, ?Throwable $...
method dueToError (line 17) | public static function dueToError(string $path, Throwable $exception):...
method noGeneratorConfigured (line 22) | public static function noGeneratorConfigured(string $path, string $ext...
FILE: src/UnableToListContents.php
class UnableToListContents (line 10) | final class UnableToListContents extends RuntimeException implements Fil...
method atLocation (line 12) | public static function atLocation(string $location, bool $deep, Throwa...
method operation (line 20) | public function operation(): string
FILE: src/UnableToMountFilesystem.php
class UnableToMountFilesystem (line 9) | class UnableToMountFilesystem extends LogicException implements Filesyst...
method becauseTheKeyIsNotValid (line 14) | public static function becauseTheKeyIsNotValid($key): UnableToMountFil...
method becauseTheFilesystemWasNotValid (line 24) | public static function becauseTheFilesystemWasNotValid($filesystem): U...
FILE: src/UnableToMoveFile.php
class UnableToMoveFile (line 10) | final class UnableToMoveFile extends RuntimeException implements Filesys...
method sourceAndDestinationAreTheSame (line 22) | public static function sourceAndDestinationAreTheSame(string $source, ...
method source (line 27) | public function source(): string
method destination (line 32) | public function destination(): string
method fromLocationTo (line 37) | public static function fromLocationTo(
method because (line 50) | public static function because(
method operation (line 63) | public function operation(): string
FILE: src/UnableToProvideChecksum.php
class UnableToProvideChecksum (line 10) | final class UnableToProvideChecksum extends RuntimeException implements ...
method __construct (line 12) | public function __construct(string $reason, string $path, ?Throwable $...
FILE: src/UnableToReadFile.php
class UnableToReadFile (line 10) | final class UnableToReadFile extends RuntimeException implements Filesys...
method fromLocation (line 22) | public static function fromLocation(string $location, string $reason =...
method operation (line 31) | public function operation(): string
method reason (line 36) | public function reason(): string
method location (line 41) | public function location(): string
FILE: src/UnableToResolveFilesystemMount.php
class UnableToResolveFilesystemMount (line 9) | class UnableToResolveFilesystemMount extends RuntimeException implements...
method becauseTheSeparatorIsMissing (line 11) | public static function becauseTheSeparatorIsMissing(string $path): Una...
method becauseTheMountWasNotRegistered (line 16) | public static function becauseTheMountWasNotRegistered(string $mountId...
FILE: src/UnableToRetrieveMetadata.php
class UnableToRetrieveMetadata (line 10) | final class UnableToRetrieveMetadata extends RuntimeException implements...
method lastModified (line 27) | public static function lastModified(string $location, string $reason =...
method visibility (line 32) | public static function visibility(string $location, string $reason = '...
method fileSize (line 37) | public static function fileSize(string $location, string $reason = '',...
method mimeType (line 42) | public static function mimeType(string $location, string $reason = '',...
method create (line 47) | public static function create(string $location, string $type, string $...
method reason (line 57) | public function reason(): string
method location (line 62) | public function location(): string
method metadataType (line 67) | public function metadataType(): string
method operation (line 72) | public function operation(): string
FILE: src/UnableToSetVisibility.php
class UnableToSetVisibility (line 13) | final class UnableToSetVisibility extends RuntimeException implements Fi...
method reason (line 25) | public function reason(): string
method atLocation (line 30) | public static function atLocation(string $filename, string $extraMessa...
method operation (line 40) | public function operation(): string
method location (line 45) | public function location(): string
FILE: src/UnableToWriteFile.php
class UnableToWriteFile (line 10) | final class UnableToWriteFile extends RuntimeException implements Filesy...
method atLocation (line 22) | public static function atLocation(string $location, string $reason = '...
method operation (line 31) | public function operation(): string
method reason (line 36) | public function reason(): string
method location (line 41) | public function location(): string
FILE: src/UnixVisibility/PortableVisibilityConverter.php
class PortableVisibilityConverter (line 10) | class PortableVisibilityConverter implements VisibilityConverter
method __construct (line 12) | public function __construct(
method forFile (line 21) | public function forFile(string $visibility): int
method forDirectory (line 30) | public function forDirectory(string $visibility): int
method inverseForFile (line 39) | public function inverseForFile(int $visibility): string
method inverseForDirectory (line 50) | public function inverseForDirectory(int $visibility): string
method defaultForDirectories (line 61) | public function defaultForDirectories(): int
method fromArray (line 69) | public static function fromArray(array $permissionMap, string $default...
FILE: src/UnixVisibility/PortableVisibilityConverterTest.php
class PortableVisibilityConverterTest (line 14) | class PortableVisibilityConverterTest extends TestCase
method determining_visibility_for_a_file (line 19) | public function determining_visibility_for_a_file(): void
method determining_an_incorrect_visibility_for_a_file (line 29) | public function determining_an_incorrect_visibility_for_a_file(): void
method determining_visibility_for_a_directory (line 39) | public function determining_visibility_for_a_directory(): void
method determining_an_incorrect_visibility_for_a_directory (line 49) | public function determining_an_incorrect_visibility_for_a_directory():...
method inversing_for_a_file (line 59) | public function inversing_for_a_file(): void
method inversing_for_a_directory (line 70) | public function inversing_for_a_directory(): void
method determining_default_for_directories (line 81) | public function determining_default_for_directories(): void
method creating_from_array (line 93) | public function creating_from_array(): void
FILE: src/UnixVisibility/VisibilityConverter.php
type VisibilityConverter (line 7) | interface VisibilityConverter
method forFile (line 9) | public function forFile(string $visibility): int;
method forDirectory (line 10) | public function forDirectory(string $visibility): int;
method inverseForFile (line 11) | public function inverseForFile(int $visibility): string;
method inverseForDirectory (line 12) | public function inverseForDirectory(int $visibility): string;
method defaultForDirectories (line 13) | public function defaultForDirectories(): int;
FILE: src/UnreadableFileEncountered.php
class UnreadableFileEncountered (line 9) | final class UnreadableFileEncountered extends RuntimeException implement...
method location (line 16) | public function location(): string
method atLocation (line 21) | public static function atLocation(string $location): UnreadableFileEnc...
FILE: src/UrlGeneration/ChainedPublicUrlGenerator.php
class ChainedPublicUrlGenerator (line 10) | final class ChainedPublicUrlGenerator implements PublicUrlGenerator
method __construct (line 15) | public function __construct(private iterable $generators)
method publicUrl (line 19) | public function publicUrl(string $path, Config $config): string
FILE: src/UrlGeneration/ChainedPublicUrlGeneratorTest.php
class ChainedPublicUrlGeneratorTest (line 9) | final class ChainedPublicUrlGeneratorTest extends TestCase
method can_generate_url_for_supported_generator (line 14) | public function can_generate_url_for_supported_generator(): void
method no_supported_generator_found_throws_exception (line 32) | public function no_supported_generator_found_throws_exception(): void
FILE: src/UrlGeneration/PrefixPublicUrlGenerator.php
class PrefixPublicUrlGenerator (line 10) | class PrefixPublicUrlGenerator implements PublicUrlGenerator
method __construct (line 14) | public function __construct(string $urlPrefix)
method publicUrl (line 19) | public function publicUrl(string $path, Config $config): string
FILE: src/UrlGeneration/PublicUrlGenerator.php
type PublicUrlGenerator (line 10) | interface PublicUrlGenerator
method publicUrl (line 15) | public function publicUrl(string $path, Config $config): string;
FILE: src/UrlGeneration/ShardedPrefixPublicUrlGenerator.php
class ShardedPrefixPublicUrlGenerator (line 13) | final class ShardedPrefixPublicUrlGenerator implements PublicUrlGenerator
method __construct (line 22) | public function __construct(array $prefixes)
method publicUrl (line 33) | public function publicUrl(string $path, Config $config): string
FILE: src/UrlGeneration/TemporaryUrlGenerator.php
type TemporaryUrlGenerator (line 10) | interface TemporaryUrlGenerator
method temporaryUrl (line 15) | public function temporaryUrl(string $path, DateTimeInterface $expiresA...
FILE: src/Visibility.php
class Visibility (line 7) | final class Visibility
FILE: src/WebDAV/ByteMarkWebDAVServerTest.php
class ByteMarkWebDAVServerTest (line 9) | class ByteMarkWebDAVServerTest extends WebDAVAdapterTestCase
method createFilesystemAdapter (line 11) | protected static function createFilesystemAdapter(): FilesystemAdapter
FILE: src/WebDAV/SabreServerTest.php
class SabreServerTest (line 10) | class SabreServerTest extends WebDAVAdapterTestCase
method createFilesystemAdapter (line 12) | protected static function createFilesystemAdapter(): FilesystemAdapter
FILE: src/WebDAV/UrlPrefixingClientStub.php
class UrlPrefixingClientStub (line 8) | class UrlPrefixingClientStub extends Client
method propFind (line 13) | public function propFind($url, array $properties, $depth = 0): array
FILE: src/WebDAV/WebDAVAdapter.php
class WebDAVAdapter (line 40) | class WebDAVAdapter implements FilesystemAdapter, PublicUrlGenerator
method __construct (line 55) | public function __construct(
method fileExists (line 65) | public function fileExists(string $path): bool
method encodePath (line 82) | protected function encodePath(string $path): string
method directoryExists (line 93) | public function directoryExists(string $path): bool
method write (line 110) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 115) | public function writeStream(string $path, $contents, Config $config): ...
method upload (line 123) | private function upload(string $path, mixed $contents): void
method read (line 140) | public function read(string $path): string
method readStream (line 157) | public function readStream(string $path)
method delete (line 177) | public function delete(string $path): void
method deleteDirectory (line 195) | public function deleteDirectory(string $path): void
method createDirectory (line 212) | public function createDirectory(string $path, Config $config): void
method setVisibility (line 246) | public function setVisibility(string $path, string $visibility): void
method visibility (line 253) | public function visibility(string $path): FileAttributes
method mimeType (line 258) | public function mimeType(string $path): FileAttributes
method lastModified (line 265) | public function lastModified(string $path): FileAttributes
method fileSize (line 272) | public function fileSize(string $path): FileAttributes
method listContents (line 279) | public function listContents(string $path, bool $deep): iterable
method normalizeObject (line 313) | private function normalizeObject(array $object): array
method move (line 337) | public function move(string $source, string $destination, Config $conf...
method manualMove (line 366) | private function manualMove(string $source, string $destination): void
method copy (line 378) | public function copy(string $source, string $destination, Config $conf...
method manualCopy (line 407) | private function manualCopy(string $source, string $destination): void
method propsIsDirectory (line 418) | private function propsIsDirectory(array $properties): bool
method createParentDirFor (line 430) | private function createParentDirFor(string $path): void
method propFind (line 441) | private function propFind(string $path, string $section, string $prope...
method publicUrl (line 458) | public function publicUrl(string $path, Config $config): string
FILE: src/WebDAV/WebDAVAdapterTestCase.php
class WebDAVAdapterTestCase (line 14) | abstract class WebDAVAdapterTestCase extends FilesystemAdapterTestCase
method setting_visibility (line 19) | public function setting_visibility(): void
method overwriting_a_file (line 32) | public function overwriting_a_file(): void
method creating_a_directory_with_leading_and_trailing_slashes (line 48) | public function creating_a_directory_with_leading_and_trailing_slashes...
method copying_a_file (line 61) | public function copying_a_file(): void
method copying_a_file_again (line 82) | public function copying_a_file_again(): void
method moving_a_file (line 103) | public function moving_a_file(): void
method moving_a_file_that_does_not_exist (line 128) | public function moving_a_file_that_does_not_exist(): void
method part_of_prefix_already_exists (line 140) | public function part_of_prefix_already_exists(): void
FILE: src/WhitespacePathNormalizer.php
class WhitespacePathNormalizer (line 7) | class WhitespacePathNormalizer implements PathNormalizer
method normalizePath (line 9) | public function normalizePath(string $path): string
method rejectFunkyWhiteSpace (line 17) | private function rejectFunkyWhiteSpace(string $path): void
method normalizeRelativePath (line 24) | private function normalizeRelativePath(string $path): string
FILE: src/WhitespacePathNormalizerTest.php
class WhitespacePathNormalizerTest (line 9) | class WhitespacePathNormalizerTest extends TestCase
method setUp (line 16) | protected function setUp(): void
method path_normalizing (line 26) | public function path_normalizing(string $input, string $expected): void
method pathProvider (line 37) | public static function pathProvider(): array
method guarding_against_path_traversal (line 67) | public function guarding_against_path_traversal(string $input): void
method rejecting_funky_whitespace (line 78) | public function rejecting_funky_whitespace(string $path): void
method dpFunkyWhitespacePaths (line 84) | public static function dpFunkyWhitespacePaths(): iterable
method invalidPathProvider (line 92) | public static function invalidPathProvider(): array
FILE: src/ZipArchive/FilesystemZipArchiveProvider.php
class FilesystemZipArchiveProvider (line 9) | class FilesystemZipArchiveProvider implements ZipArchiveProvider
method __construct (line 16) | public function __construct(private string $filename, private int $loc...
method createZipArchive (line 20) | public function createZipArchive(): ZipArchive
method createParentDirectoryForZipArchive (line 30) | private function createParentDirectoryForZipArchive(string $fullPath):...
method openZipArchive (line 43) | private function openZipArchive(): ZipArchive
FILE: src/ZipArchive/NoRootPrefixZipArchiveAdapterTest.php
class NoRootPrefixZipArchiveAdapterTest (line 10) | final class NoRootPrefixZipArchiveAdapterTest extends ZipArchiveAdapterT...
method getRoot (line 12) | protected static function getRoot(): string
FILE: src/ZipArchive/PrefixedRootZipArchiveAdapterTest.php
class PrefixedRootZipArchiveAdapterTest (line 10) | final class PrefixedRootZipArchiveAdapterTest extends ZipArchiveAdapterT...
method getRoot (line 12) | protected static function getRoot(): string
FILE: src/ZipArchive/StubZipArchive.php
class StubZipArchive (line 9) | class StubZipArchive extends ZipArchive
method failNextDirectoryCreation (line 17) | public function failNextDirectoryCreation(): void
method addEmptyDir (line 28) | public function addEmptyDir($dirname, $flags = 0): bool
method failNextWrite (line 39) | public function failNextWrite(): void
method addFromString (line 51) | public function addFromString($localname, $contents, $flags = 0): bool
method failNextDeleteName (line 62) | public function failNextDeleteName(): void
method deleteName (line 70) | public function deleteName($name): bool
method failWhenSettingVisibility (line 81) | public function failWhenSettingVisibility(): void
method setExternalAttributesName (line 86) | public function setExternalAttributesName($name, $opsys, $attr, $flags...
method failWhenDeletingAnIndex (line 97) | public function failWhenDeletingAnIndex(): void
method deleteIndex (line 102) | public function deleteIndex($index): bool
FILE: src/ZipArchive/StubZipArchiveProvider.php
class StubZipArchiveProvider (line 9) | class StubZipArchiveProvider implements ZipArchiveProvider
method __construct (line 18) | public function __construct(private string $filename, int $localDirect...
method createZipArchive (line 23) | public function createZipArchive(): ZipArchive
method stubbedZipArchive (line 37) | public function stubbedZipArchive(): StubZipArchive
FILE: src/ZipArchive/UnableToCreateParentDirectory.php
class UnableToCreateParentDirectory (line 9) | class UnableToCreateParentDirectory extends RuntimeException implements ...
method atLocation (line 11) | public static function atLocation(string $location, string $reason = '...
FILE: src/ZipArchive/UnableToOpenZipArchive.php
class UnableToOpenZipArchive (line 9) | final class UnableToOpenZipArchive extends RuntimeException implements Z...
method atLocation (line 11) | public static function atLocation(string $location, string $reason = '...
FILE: src/ZipArchive/ZipArchiveAdapter.php
class ZipArchiveAdapter (line 34) | final class ZipArchiveAdapter implements FilesystemAdapter
method __construct (line 40) | public function __construct(
method fileExists (line 52) | public function fileExists(string $path): bool
method write (line 61) | public function write(string $path, string $contents, Config $config):...
method writeStream (line 89) | public function writeStream(string $path, $contents, Config $config): ...
method read (line 100) | public function read(string $path): string
method readStream (line 114) | public function readStream(string $path)
method delete (line 133) | public function delete(string $path): void
method deleteDirectory (line 146) | public function deleteDirectory(string $path): void
method createDirectory (line 174) | public function createDirectory(string $path, Config $config): void
method directoryExists (line 183) | public function directoryExists(string $path): bool
method setVisibility (line 191) | public function setVisibility(string $path, string $visibility): void
method visibility (line 212) | public function visibility(string $path): FileAttributes
method mimeType (line 235) | public function mimeType(string $path): FileAttributes
method lastModified (line 252) | public function lastModified(string $path): FileAttributes
method fileSize (line 266) | public function fileSize(string $path): FileAttributes
method listContents (line 284) | public function listContents(string $path, bool $deep): iterable
method yieldItemsFrom (line 327) | private function yieldItemsFrom(array $items): Generator
method move (line 332) | public function move(string $source, string $destination, Config $conf...
method copy (line 366) | public function copy(string $source, string $destination, Config $conf...
method ensureParentDirectoryExists (line 380) | private function ensureParentDirectoryExists(string $path, Config $con...
method ensureDirectoryExists (line 391) | private function ensureDirectoryExists(string $dirname, Config $config...
method isDirectoryPath (line 420) | private function isDirectoryPath(string $path): bool
method isAtRootDirectory (line 425) | private function isAtRootDirectory(string $directoryRoot, string $path...
method setVisibilityAttribute (line 436) | private function setVisibilityAttribute(string $statsName, string $vis...
FILE: src/ZipArchive/ZipArchiveAdapterTestCase.php
class ZipArchiveAdapterTestCase (line 25) | abstract class ZipArchiveAdapterTestCase extends FilesystemAdapterTestCase
method setUp (line 34) | protected function setUp(): void
method tearDownAfterClass (line 41) | public static function tearDownAfterClass(): void
method tearDown (line 46) | protected function tearDown(): void
method createFilesystemAdapter (line 51) | protected static function createFilesystemAdapter(): FilesystemAdapter
method getRoot (line 58) | abstract protected static function getRoot(): string;
method not_being_able_to_create_the_parent_directory (line 63) | public function not_being_able_to_create_the_parent_directory(): void
method not_being_able_to_write_a_file_because_the_parent_directory_could_not_be_created (line 74) | public function not_being_able_to_write_a_file_because_the_parent_dire...
method scenarios_that_cause_writing_a_file_to_fail (line 88) | public function scenarios_that_cause_writing_a_file_to_fail(callable $...
method scenariosThatCauseWritesToFail (line 101) | public static function scenariosThatCauseWritesToFail(): Generator
method failing_to_delete_a_file (line 119) | public function failing_to_delete_a_file(): void
method deleting_a_directory (line 131) | public function deleting_a_directory(): void
method deleting_a_prefixed_directory (line 150) | public function deleting_a_prefixed_directory(): void
method list_root_directory (line 169) | public function list_root_directory(): void
method failing_to_create_a_directory (line 183) | public function failing_to_create_a_directory(): void
method failing_to_create_a_directory_because_setting_visibility_fails (line 195) | public function failing_to_create_a_directory_because_setting_visibili...
method failing_to_delete_a_directory (line 207) | public function failing_to_delete_a_directory(): void
method setting_visibility_on_a_directory (line 221) | public function setting_visibility_on_a_directory(): void
method failing_to_move_a_file (line 233) | public function failing_to_move_a_file(): void
method failing_to_copy_a_file (line 247) | public function failing_to_copy_a_file(): void
method failing_to_set_visibility_because_the_file_does_not_exist (line 261) | public function failing_to_set_visibility_because_the_file_does_not_ex...
method deleting_a_directory_with_files_in_it (line 271) | public function deleting_a_directory_with_files_in_it(): void
method failing_to_set_visibility_because_setting_it_fails (line 285) | public function failing_to_set_visibility_because_setting_it_fails(): ...
method moving_a_file_and_overwriting (line 300) | public function moving_a_file_and_overwriting(): void
method removeZipArchive (line 328) | protected static function removeZipArchive(): void
FILE: src/ZipArchive/ZipArchiveException.php
type ZipArchiveException (line 9) | interface ZipArchiveException extends FilesystemException
FILE: src/ZipArchive/ZipArchiveProvider.php
type ZipArchiveProvider (line 9) | interface ZipArchiveProvider
method createZipArchive (line 11) | public function createZipArchive(): ZipArchive;
Condensed preview — 293 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (785K chars).
[
{
"path": ".dockerignore",
"chars": 5,
"preview": ".git\n"
},
{
"path": ".editorconfig",
"chars": 137,
"preview": "[*]\nindent_style = space\n\n[*.yml]\nindent_size = 2\n\n[composer.json]\nindent_size = 4\n\n[*.php]\nend_of_line = lf\ninsert_fina"
},
{
"path": ".gitattributes",
"chars": 1278,
"preview": "* text=auto\n\n/.docker export-ignore\n/.dockerignore export-ignore\n/docker-compose.yml export-ignore\n/config.subsplit-publ"
},
{
"path": ".github/ISSUE_TEMPLATE/Bug.md",
"chars": 501,
"preview": "---\nname: 🐛 Bug\nabout: Did you encounter a bug?\n---\n\n### Bug Report\n\n<!-- Fill in the relevant information below to help"
},
{
"path": ".github/ISSUE_TEMPLATE/Feature_Request.md",
"chars": 528,
"preview": "---\nname: 🎉 Feature Request\nabout: Do you have a new feature in mind?\n---\n\n### Feature Request\n\n<!-- Fill in the relevan"
},
{
"path": ".github/ISSUE_TEMPLATE/Question.md",
"chars": 315,
"preview": "---\nname: ❓ Question\nabout: Are you unsure about something?\n---\n\n### Question\n\n<!-- Fill in the relevant information bel"
},
{
"path": ".github/release.yml",
"chars": 270,
"preview": "changelog:\n categories:\n - title: Breaking Changes 🛠\n labels:\n - Semver-Major\n - breaking-change\n"
},
{
"path": ".github/stale.yml",
"chars": 696,
"preview": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 60\n# Number of days of inactivity before a "
},
{
"path": ".github/workflows/publish-subsplits.yml",
"chars": 990,
"preview": "---\nname: Sub-Split Publishing\non:\n push:\n branches:\n - 3.x\n create:\n tags:\n - '3.*'\n delete:\n tag"
},
{
"path": ".github/workflows/quality-assurance.yml",
"chars": 2514,
"preview": "---\nname: Quality Assurance\nconcurrency:\n group: ${{ github.ref }}\n cancel-in-progress: true\non:\n push:\n paths:\n "
},
{
"path": ".github/workflows/set-subsplit-default-branch.yml",
"chars": 932,
"preview": "---\nname: Update default sub-split branch\n\non: workflow_dispatch\n\njobs:\n set-default-branch:\n name: Set default git "
},
{
"path": ".gitignore",
"chars": 164,
"preview": "/vendor/\n/coverage/\n/.phpunit.result.cache\n/phpunit.xml\n/composer.lock\n/index_*.php\n/.php-cs-fixer.php\n/.php-cs-fixer.ca"
},
{
"path": ".php-cs-fixer.dist.php",
"chars": 1382,
"preview": "<?php\n\n$finder = PhpCsFixer\\Finder::create()\n ->in([__DIR__ . '/'])\n ->exclude(__DIR__ . '/vendor');\n\nreturn (new "
},
{
"path": "CHANGELOG.md",
"chars": 18359,
"preview": "# Changelog\n\n## 3.32.0 - 2026-02-25\n\n### Changes\n\n- [AwsS3V3] Allow SSE-C options when fetching file metadata\n\n## 3.31.0"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5222,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "INFO.md",
"chars": 139,
"preview": "View the docs at: https://flysystem.thephpleague.com/docs/ \nChangelog at: https://github.com/thephpleague/flysystem/blo"
},
{
"path": "LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "bin/.gitignore",
"chars": 16,
"preview": "renamespace.php\n"
},
{
"path": "bin/check-versions.php",
"chars": 3932,
"preview": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * This script check for composer dependency incompatibilities:.\n *\n * - All requi"
},
{
"path": "bin/close-subsplit-prs.yml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "bin/set-flysystem-version.php",
"chars": 1177,
"preview": "<?php\n\nuse League\\Flysystem\\FileAttributes;\nuse League\\Flysystem\\Filesystem;\nuse League\\Flysystem\\Local\\LocalFilesystemA"
},
{
"path": "bin/tools.php",
"chars": 210,
"preview": "<?php\n\ninclude_once __DIR__ . '/../vendor/autoload.php';\n\nfunction write_line(string $line)\n{\n fwrite(STDOUT, \"{$line"
},
{
"path": "bin/update-subsplit-closers.php",
"chars": 582,
"preview": "<?php\n\nuse League\\Flysystem\\Filesystem;\nuse League\\Flysystem\\Local\\LocalFilesystemAdapter;\n\ninclude __DIR__ . '/../vendo"
},
{
"path": "composer.json",
"chars": 2068,
"preview": "{\n \"name\": \"league/flysystem\",\n \"description\": \"File storage abstraction for PHP\",\n \"keywords\": [\n \"file"
},
{
"path": "config.subsplit-publish.json",
"chars": 2656,
"preview": "{\n \"sub-splits\": [\n {\n \"name\": \"ftp\",\n \"directory\": \"src/Ftp\",\n \"target\": \"gi"
},
{
"path": "docker-compose.yml",
"chars": 2235,
"preview": "---\nversion: \"3\"\nservices:\n mongodb:\n image: mongo:7\n ports:\n - \"27017:27017\"\n sabredav:\n image: php:8.1"
},
{
"path": "mocked-functions.php",
"chars": 3492,
"preview": "<?php\n\nnamespace League\\Flysystem\\Local {\n function rmdir(...$arguments)\n {\n if ( ! is_mocked('rmdir')) {\n "
},
{
"path": "phpstan-baseline.neon",
"chars": 5450,
"preview": "parameters:\n\tignoreErrors:\n\t\t-\n\t\t\tmessage: \"#^Parameter \\\\$connection of method League\\\\\\\\Flysystem\\\\\\\\Ftp\\\\\\\\FtpAdapter"
},
{
"path": "phpstan.neon",
"chars": 1019,
"preview": "includes:\n - phpstan-baseline.neon\nparameters:\n level: 6\n paths:\n - src\n checkMissingIterableValueTyp"
},
{
"path": "phpunit.php",
"chars": 158,
"preview": "<?php\n\ninclude __DIR__ . '/vendor/autoload.php';\ninclude __DIR__ . '/src/AdapterTestUtilities/test-functions.php';\ninclu"
},
{
"path": "phpunit.xml.dist",
"chars": 544,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit colors=\"true\" bootstrap=\"phpunit.php\">\n <testsuites>\n <testsui"
},
{
"path": "readme.md",
"chars": 3954,
"preview": "# League\\Flysystem\n\n[](https://twitter.com/frankdej"
},
{
"path": "src/AdapterTestUtilities/.gitattributes",
"chars": 88,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\nREADME.md export-ignore\n"
},
{
"path": "src/AdapterTestUtilities/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/AdapterTestUtilities/ExceptionThrowingFilesystemAdapter.php",
"chars": 4381,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AdapterTestUtilities;\n\nuse League\\Flysystem\\Config;\nuse Leag"
},
{
"path": "src/AdapterTestUtilities/FilesystemAdapterTestCase.php",
"chars": 30231,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AdapterTestUtilities;\n\nuse const PHP_EOL;\nuse DateInterval;\n"
},
{
"path": "src/AdapterTestUtilities/README.md",
"chars": 366,
"preview": "## Flysystem Adapter Test Utilities\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: https://github.com/t"
},
{
"path": "src/AdapterTestUtilities/RetryOnTestException.php",
"chars": 2292,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AdapterTestUtilities;\n\nuse const PHP_EOL;\nuse const STDOUT;\n"
},
{
"path": "src/AdapterTestUtilities/ToxiproxyManagement.php",
"chars": 2155,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AdapterTestUtilities;\n\nuse GuzzleHttp\\Client;\n\n/**\n * This c"
},
{
"path": "src/AdapterTestUtilities/composer.json",
"chars": 669,
"preview": "{\n \"name\": \"league/flysystem-adapter-test-utilities\",\n \"description\": \"Flysystem utilities for testing adapters.\","
},
{
"path": "src/AdapterTestUtilities/test-functions.php",
"chars": 1152,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nfunction return_mocked_value(string $name)\n{\n return array_shift($_ENV['__FM:RETURNS"
},
{
"path": "src/AdapterTestUtilities/test_files/unknown-mime-type.md5",
"chars": 32,
"preview": "141d15ed35fc57dcc3c72bba881742b1"
},
{
"path": "src/AsyncAwsS3/.gitattributes",
"chars": 167,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/AsyncAwsS3/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/AsyncAwsS3/AsyncAwsS3Adapter.php",
"chars": 19402,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AsyncAwsS3;\n\nuse AsyncAws\\Core\\Exception\\Http\\ClientExceptio"
},
{
"path": "src/AsyncAwsS3/AsyncAwsS3AdapterTest.php",
"chars": 16086,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AsyncAwsS3;\n\nuse AsyncAws\\Core\\Exception\\Http\\ClientExceptio"
},
{
"path": "src/AsyncAwsS3/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/AsyncAwsS3/PortableVisibilityConverter.php",
"chars": 1562,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AsyncAwsS3;\n\nuse AsyncAws\\S3\\ValueObject\\Grant;\nuse League\\F"
},
{
"path": "src/AsyncAwsS3/README.md",
"chars": 298,
"preview": "## Sub-split of Flysystem for AsyncAws S3.\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: https://githu"
},
{
"path": "src/AsyncAwsS3/S3ClientStub.php",
"chars": 5545,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AsyncAwsS3;\n\nuse AsyncAws\\Core\\Exception\\Exception;\nuse Asyn"
},
{
"path": "src/AsyncAwsS3/VisibilityConverter.php",
"chars": 369,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AsyncAwsS3;\n\nuse AsyncAws\\S3\\ValueObject\\Grant;\n\ninterface V"
},
{
"path": "src/AsyncAwsS3/composer.json",
"chars": 801,
"preview": "{\n \"name\": \"league/flysystem-async-aws-s3\",\n \"description\": \"AsyncAws S3 filesystem adapter for Flysystem.\",\n \""
},
{
"path": "src/AwsS3V3/.gitattributes",
"chars": 167,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/AwsS3V3/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/AwsS3V3/AwsS3V3Adapter.php",
"chars": 17385,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AwsS3V3;\n\nuse Aws\\Api\\DateTimeResult;\nuse Aws\\S3\\S3ClientInt"
},
{
"path": "src/AwsS3V3/AwsS3V3AdapterTest.php",
"chars": 15282,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AwsS3V3;\n\nuse Aws\\Result;\nuse Aws\\S3\\S3Client;\nuse Aws\\S3\\S3"
},
{
"path": "src/AwsS3V3/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/AwsS3V3/PortableVisibilityConverter.php",
"chars": 1270,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AwsS3V3;\n\nuse League\\Flysystem\\Visibility;\n\nclass PortableVi"
},
{
"path": "src/AwsS3V3/README.md",
"chars": 288,
"preview": "## Sub-split of Flysystem for AWS S3.\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: https://github.com"
},
{
"path": "src/AwsS3V3/S3ClientStub.php",
"chars": 4642,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AwsS3V3;\n\nuse Aws\\Command;\nuse Aws\\CommandInterface;\nuse Aws"
},
{
"path": "src/AwsS3V3/VisibilityConverter.php",
"chars": 282,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AwsS3V3;\n\ninterface VisibilityConverter\n{\n public functio"
},
{
"path": "src/AwsS3V3/composer.json",
"chars": 742,
"preview": "{\n \"name\": \"league/flysystem-aws-s3-v3\",\n \"description\": \"AWS S3 filesystem adapter for Flysystem.\",\n \"keywords"
},
{
"path": "src/AzureBlobStorage/.gitattributes",
"chars": 167,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/AzureBlobStorage/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/AzureBlobStorage/AzureBlobStorageAdapter.php",
"chars": 14202,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AzureBlobStorage;\n\nuse DateTime;\nuse DateTimeInterface;\nuse "
},
{
"path": "src/AzureBlobStorage/AzureBlobStorageAdapterTest.php",
"chars": 6041,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\AzureBlobStorage;\n\nuse League\\Flysystem\\AdapterTestUtilities"
},
{
"path": "src/AzureBlobStorage/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/AzureBlobStorage/README.md",
"chars": 162,
"preview": "## Sub-split for Flysystem's Azure Blob Storage Adapter\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: "
},
{
"path": "src/AzureBlobStorage/composer.json",
"chars": 500,
"preview": "{\n \"name\": \"league/flysystem-azure-blob-storage\",\n \"autoload\": {\n \"psr-4\": {\n \"League\\\\Flysystem"
},
{
"path": "src/CalculateChecksumFromStream.php",
"chars": 793,
"preview": "<?php\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse function hash_final;\nuse function hash_init;\nuse functi"
},
{
"path": "src/ChecksumAlgoIsNotSupported.php",
"chars": 169,
"preview": "<?php\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse InvalidArgumentException;\n\nfinal class ChecksumAlgoIsNo"
},
{
"path": "src/ChecksumProvider.php",
"chars": 291,
"preview": "<?php\n\nnamespace League\\Flysystem;\n\ninterface ChecksumProvider\n{\n /**\n * @return string MD5 hash of the file cont"
},
{
"path": "src/Config.php",
"chars": 1421,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse function array_diff_key;\nuse function array_flip;\nuse "
},
{
"path": "src/ConfigTest.php",
"chars": 1801,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass ConfigTest extends "
},
{
"path": "src/CorruptedPathDetected.php",
"chars": 316,
"preview": "<?php\n\nnamespace League\\Flysystem;\n\nuse RuntimeException;\n\nfinal class CorruptedPathDetected extends RuntimeException im"
},
{
"path": "src/DecoratedAdapter.php",
"chars": 2421,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nabstract class DecoratedAdapter implements FilesystemAdapt"
},
{
"path": "src/DirectoryAttributes.php",
"chars": 2071,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nclass DirectoryAttributes implements StorageAttributes\n{\n "
},
{
"path": "src/DirectoryAttributesTest.php",
"chars": 1647,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @group core\n */\ncl"
},
{
"path": "src/DirectoryListing.php",
"chars": 2078,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse ArrayIterator;\nuse Generator;\nuse IteratorAggregate;\nu"
},
{
"path": "src/DirectoryListingTest.php",
"chars": 3726,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse Generator;\nuse PHPUnit\\Framework\\TestCase;\n\nuse functi"
},
{
"path": "src/ExceptionInformationTest.php",
"chars": 6280,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @group core\n */\ncl"
},
{
"path": "src/FileAttributes.php",
"chars": 2562,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nclass FileAttributes implements StorageAttributes\n{\n us"
},
{
"path": "src/FileAttributesTest.php",
"chars": 3286,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse Generator;\nuse PHPUnit\\Framework\\TestCase;\n\nuse Runtim"
},
{
"path": "src/Filesystem.php",
"chars": 9850,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse DateTimeInterface;\nuse Generator;\nuse League\\Flysystem"
},
{
"path": "src/FilesystemAdapter.php",
"chars": 2784,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\ninterface FilesystemAdapter\n{\n /**\n * @throws Files"
},
{
"path": "src/FilesystemException.php",
"chars": 130,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse Throwable;\n\ninterface FilesystemException extends Thro"
},
{
"path": "src/FilesystemOperationFailed.php",
"chars": 954,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\ninterface FilesystemOperationFailed extends FilesystemExce"
},
{
"path": "src/FilesystemOperator.php",
"chars": 138,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\ninterface FilesystemOperator extends FilesystemReader, Fil"
},
{
"path": "src/FilesystemReader.php",
"chars": 2169,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse DateTimeInterface;\n\n/**\n * This interface contains eve"
},
{
"path": "src/FilesystemTest.php",
"chars": 26343,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse DateTimeImmutable;\nuse DateTimeInterface;\nuse Generato"
},
{
"path": "src/FilesystemWriter.php",
"chars": 1448,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\ninterface FilesystemWriter\n{\n /**\n * @throws Unable"
},
{
"path": "src/Ftp/.gitattributes",
"chars": 171,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/Ftp/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/Ftp/ConnectionProvider.php",
"chars": 208,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\ninterface ConnectionProvider\n{\n /**\n * @return "
},
{
"path": "src/Ftp/ConnectivityChecker.php",
"chars": 203,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\ninterface ConnectivityChecker\n{\n /**\n * @param "
},
{
"path": "src/Ftp/ConnectivityCheckerThatCanFail.php",
"chars": 645,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nclass ConnectivityCheckerThatCanFail implements Connec"
},
{
"path": "src/Ftp/FtpAdapter.php",
"chars": 22337,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse DateTime;\nuse Generator;\nuse League\\Flysystem\\Conf"
},
{
"path": "src/Ftp/FtpAdapterTest.php",
"chars": 3478,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\FilesystemAdapter;\n\nuse function "
},
{
"path": "src/Ftp/FtpAdapterTestCase.php",
"chars": 11631,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse Generator;\nuse League\\Flysystem\\AdapterTestUtiliti"
},
{
"path": "src/Ftp/FtpConnectionException.php",
"chars": 174,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\FilesystemException;\n\ninterface F"
},
{
"path": "src/Ftp/FtpConnectionOptions.php",
"chars": 2955,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse const FTP_BINARY;\n\nclass FtpConnectionOptions\n{\n "
},
{
"path": "src/Ftp/FtpConnectionProvider.php",
"chars": 3200,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse const FTP_USEPASVADDRESS;\nuse function error_clear"
},
{
"path": "src/Ftp/FtpConnectionProviderTest.php",
"chars": 5590,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\AdapterTestUtilities\\RetryOnTestE"
},
{
"path": "src/Ftp/FtpdAdapterTest.php",
"chars": 732,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\FilesystemAdapter;\n\n/**\n * @group"
},
{
"path": "src/Ftp/InvalidListResponseReceived.php",
"chars": 225,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\FilesystemException;\nuse RuntimeE"
},
{
"path": "src/Ftp/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/Ftp/NoopCommandConnectivityChecker.php",
"chars": 602,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse TypeError;\nuse ValueError;\n\nclass NoopCommandConne"
},
{
"path": "src/Ftp/NoopCommandConnectivityCheckerTest.php",
"chars": 1594,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\AdapterTestUtilities\\RetryOnTestE"
},
{
"path": "src/Ftp/README.md",
"chars": 273,
"preview": "## Sub-split of Flysystem for FTP.\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: https://github.com/th"
},
{
"path": "src/Ftp/RawListFtpConnectivityChecker.php",
"chars": 428,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse ValueError;\n\nclass RawListFtpConnectivityChecker i"
},
{
"path": "src/Ftp/RawListFtpConnectivityCheckerTest.php",
"chars": 1115,
"preview": "<?php\n\nnamespace League\\Flysystem\\Ftp;\n\nuse League\\Flysystem\\AdapterTestUtilities\\RetryOnTestException;\nuse PHPUnit\\Fram"
},
{
"path": "src/Ftp/StubConnectionProvider.php",
"chars": 402,
"preview": "<?php\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nclass StubConnectionProvider implements ConnectionProvi"
},
{
"path": "src/Ftp/UnableToAuthenticate.php",
"chars": 301,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse RuntimeException;\n\nfinal class UnableToAuthenticat"
},
{
"path": "src/Ftp/UnableToConnectToFtpHost.php",
"chars": 479,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse RuntimeException;\n\nfinal class UnableToConnectToFt"
},
{
"path": "src/Ftp/UnableToEnableUtf8Mode.php",
"chars": 187,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse RuntimeException;\n\nfinal class UnableToEnableUtf8M"
},
{
"path": "src/Ftp/UnableToMakeConnectionPassive.php",
"chars": 188,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse RuntimeException;\n\nclass UnableToMakeConnectionPas"
},
{
"path": "src/Ftp/UnableToResolveConnectionRoot.php",
"chars": 926,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse RuntimeException;\nuse Throwable;\n\nfinal class Unab"
},
{
"path": "src/Ftp/UnableToSetFtpOption.php",
"chars": 353,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Ftp;\n\nuse RuntimeException;\n\nclass UnableToSetFtpOption exte"
},
{
"path": "src/Ftp/composer.json",
"chars": 638,
"preview": "{\n \"name\": \"league/flysystem-ftp\",\n \"description\": \"FTP filesystem adapter for Flysystem.\",\n \"keywords\": [\"file"
},
{
"path": "src/GoogleCloudStorage/.gitattributes",
"chars": 141,
"preview": "* text=auto\n\n/.github export-ignore\n/.gitattributes export-ignore\n/.gitignore export-ignore\n/**/*Test.php export-ignore\n"
},
{
"path": "src/GoogleCloudStorage/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/GoogleCloudStorage/GoogleCloudStorageAdapter.php",
"chars": 13901,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse DateTimeInterface;\nuse Google\\Cloud"
},
{
"path": "src/GoogleCloudStorage/GoogleCloudStorageAdapterTest.php",
"chars": 5062,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse League\\Flysystem\\AdapterTestUtiliti"
},
{
"path": "src/GoogleCloudStorage/GoogleCloudStorageAdapterWithoutAclTest.php",
"chars": 421,
"preview": "<?php\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nclass GoogleCloudStorageAdapterWithoutAc"
},
{
"path": "src/GoogleCloudStorage/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/GoogleCloudStorage/PortableVisibilityHandler.php",
"chars": 1924,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse Google\\Cloud\\Core\\Exception\\NotFoun"
},
{
"path": "src/GoogleCloudStorage/README.md",
"chars": 330,
"preview": "## Sub-split of Flysystem for Google Cloud Storage (GCS).\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit"
},
{
"path": "src/GoogleCloudStorage/StubRiggedBucket.php",
"chars": 1373,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse Google\\Cloud\\Storage\\Bucket;\nuse Lo"
},
{
"path": "src/GoogleCloudStorage/StubStorageClient.php",
"chars": 942,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse Google\\Cloud\\Storage\\StorageClient;"
},
{
"path": "src/GoogleCloudStorage/UniformBucketLevelAccessVisibility.php",
"chars": 643,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse Google\\Cloud\\Storage\\StorageObject;"
},
{
"path": "src/GoogleCloudStorage/VisibilityHandler.php",
"chars": 385,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GoogleCloudStorage;\n\nuse Google\\Cloud\\Storage\\StorageObject;"
},
{
"path": "src/GoogleCloudStorage/composer.json",
"chars": 693,
"preview": "{\n \"name\": \"league/flysystem-google-cloud-storage\",\n \"description\": \"Google Cloud Storage adapter for Flysystem.\","
},
{
"path": "src/GridFS/.gitattributes",
"chars": 167,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/GridFS/.github/workflows/close-subsplit-prs.yaml",
"chars": 683,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/GridFS/GridFSAdapter.php",
"chars": 15711,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GridFS;\n\nuse League\\Flysystem\\Config;\nuse League\\Flysystem\\D"
},
{
"path": "src/GridFS/GridFSAdapterTest.php",
"chars": 7522,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\GridFS;\n\nuse League\\Flysystem\\AdapterTestUtilities\\Filesyste"
},
{
"path": "src/GridFS/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2024-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/GridFS/README.md",
"chars": 296,
"preview": "## Sub-split for Flysystem's MongoDB GridFS Adapter\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: http"
},
{
"path": "src/GridFS/composer.json",
"chars": 551,
"preview": "{\n \"name\": \"league/flysystem-gridfs\",\n \"autoload\": {\n \"psr-4\": {\n \"League\\\\Flysystem\\\\GridFS\\\\\":"
},
{
"path": "src/InMemory/.gitattributes",
"chars": 140,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\nREAD"
},
{
"path": "src/InMemory/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/InMemory/InMemoryFile.php",
"chars": 1476,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\InMemory;\n\nuse const FILEINFO_MIME_TYPE;\nuse finfo;\n\n/**\n * "
},
{
"path": "src/InMemory/InMemoryFilesystemAdapter.php",
"chars": 8574,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\InMemory;\n\nuse League\\Flysystem\\Config;\nuse League\\Flysystem"
},
{
"path": "src/InMemory/InMemoryFilesystemAdapterTest.php",
"chars": 8634,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\InMemory;\n\nuse League\\Flysystem\\AdapterTestUtilities\\Filesys"
},
{
"path": "src/InMemory/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/InMemory/README.md",
"chars": 301,
"preview": "## Sub-split of Flysystem for in-memory file storage.\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: ht"
},
{
"path": "src/InMemory/StaticInMemoryAdapterRegistry.php",
"chars": 465,
"preview": "<?php\n\nnamespace League\\Flysystem\\InMemory;\n\nclass StaticInMemoryAdapterRegistry\n{\n /** @var array<string, InMemoryFi"
},
{
"path": "src/InMemory/StaticInMemoryAdapterRegistryTest.php",
"chars": 1721,
"preview": "<?php\n\nnamespace League\\Flysystem\\InMemory;\n\nuse League\\Flysystem\\Config;\nuse League\\Flysystem\\FilesystemAdapter;\n\nclass"
},
{
"path": "src/InMemory/composer.json",
"chars": 627,
"preview": "{\n \"name\": \"league/flysystem-memory\",\n \"description\": \"In-memory filesystem adapter for Flysystem.\",\n \"keywords"
},
{
"path": "src/InvalidStreamProvided.php",
"chars": 225,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse InvalidArgumentException as BaseInvalidArgumentExcepti"
},
{
"path": "src/InvalidVisibilityProvided.php",
"chars": 553,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse InvalidArgumentException;\n\nuse function var_export;\n\nc"
},
{
"path": "src/Local/.gitattributes",
"chars": 140,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\nREAD"
},
{
"path": "src/Local/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/Local/FallbackMimeTypeDetector.php",
"chars": 1472,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Local;\n\nuse League\\MimeTypeDetection\\MimeTypeDetector;\nuse f"
},
{
"path": "src/Local/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/Local/LocalFilesystemAdapter.php",
"chars": 15618,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Local;\n\nuse const DIRECTORY_SEPARATOR;\nuse const LOCK_EX;\nus"
},
{
"path": "src/Local/LocalFilesystemAdapterTest.php",
"chars": 27071,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\Local;\n\nuse const LOCK_EX;\nuse League\\Flysystem\\AdapterTestU"
},
{
"path": "src/Local/README.md",
"chars": 292,
"preview": "## Sub-split of Flysystem for local file storage.\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: https:"
},
{
"path": "src/Local/composer.json",
"chars": 634,
"preview": "{\n \"name\": \"league/flysystem-local\",\n \"description\": \"Local filesystem adapter for Flysystem.\",\n \"keywords\": [\""
},
{
"path": "src/MountManager.php",
"chars": 15359,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse DateTimeInterface;\nuse Throwable;\n\nuse function compac"
},
{
"path": "src/MountManagerTest.php",
"chars": 19830,
"preview": "<?php\n\nnamespace League\\Flysystem;\n\nuse League\\Flysystem\\AdapterTestUtilities\\ExceptionThrowingFilesystemAdapter;\nuse Le"
},
{
"path": "src/PathNormalizer.php",
"chars": 148,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\ninterface PathNormalizer\n{\n public function normalizePa"
},
{
"path": "src/PathPrefixer.php",
"chars": 1158,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse function rtrim;\nuse function strlen;\nuse function subs"
},
{
"path": "src/PathPrefixerTest.php",
"chars": 3262,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass PathPrefixerTest ex"
},
{
"path": "src/PathPrefixing/.gitattributes",
"chars": 140,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\nREAD"
},
{
"path": "src/PathPrefixing/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/PathPrefixing/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/PathPrefixing/PathPrefixedAdapter.php",
"chars": 8010,
"preview": "<?php\n\nnamespace League\\Flysystem\\PathPrefixing;\n\nuse DateTimeInterface;\nuse Generator;\nuse League\\Flysystem\\CalculateCh"
},
{
"path": "src/PathPrefixing/PathPrefixedAdapterTest.php",
"chars": 5236,
"preview": "<?php\n\nnamespace League\\Flysystem\\PathPrefixing;\n\nuse League\\Flysystem\\ChecksumProvider;\nuse League\\Flysystem\\Config;\nus"
},
{
"path": "src/PathPrefixing/README.md",
"chars": 324,
"preview": "## Sub-split of Flysystem for path prefixed adapter decoration.\n\n> ⚠️ this is a sub-split, for pull requests and issues,"
},
{
"path": "src/PathPrefixing/composer.json",
"chars": 581,
"preview": "{\n \"name\": \"league/flysystem-path-prefixing\",\n \"description\": \"Path prefixing filesystem adapter for Flysystem.\",\n"
},
{
"path": "src/PathTraversalDetected.php",
"chars": 482,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem;\n\nuse RuntimeException;\n\nclass PathTraversalDetected extends"
},
{
"path": "src/PhpseclibV2/.gitattributes",
"chars": 167,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/PhpseclibV2/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/PhpseclibV2/ConnectionProvider.php",
"chars": 360,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\n\n/**\n * @deprecated Th"
},
{
"path": "src/PhpseclibV2/ConnectivityChecker.php",
"chars": 373,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\n\n/**\n * @deprecated Th"
},
{
"path": "src/PhpseclibV2/FixatedConnectivityChecker.php",
"chars": 841,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\n\n/**\n * @deprecated Th"
},
{
"path": "src/PhpseclibV2/README.md",
"chars": 444,
"preview": "# CAUTION: This package is deprecated since Flysystem 3.0 Instead, use the [Flysystem for SFTP v3](https://github.com/th"
},
{
"path": "src/PhpseclibV2/SftpAdapter.php",
"chars": 12174,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse League\\Flysystem\\Config;\nuse League\\Flysys"
},
{
"path": "src/PhpseclibV2/SftpAdapterTest.php",
"chars": 5947,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse League\\Flysystem\\AdapterTestUtilities\\File"
},
{
"path": "src/PhpseclibV2/SftpConnectionProvider.php",
"chars": 6147,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Crypt\\RSA;\nuse phpseclib\\Net\\SFT"
},
{
"path": "src/PhpseclibV2/SftpConnectionProviderTest.php",
"chars": 6606,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\nuse PHPUnit\\Framework\\"
},
{
"path": "src/PhpseclibV2/SftpStub.php",
"chars": 2384,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\n\n/**\n * @internal This"
},
{
"path": "src/PhpseclibV2/SimpleConnectivityChecker.php",
"chars": 472,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\n\n/**\n * @deprecated Th"
},
{
"path": "src/PhpseclibV2/StubSftpConnectionProvider.php",
"chars": 1274,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse phpseclib\\Net\\SFTP;\n\n/**\n * @deprecated Th"
},
{
"path": "src/PhpseclibV2/UnableToAuthenticate.php",
"chars": 903,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse League\\Flysystem\\FilesystemException;\nuse "
},
{
"path": "src/PhpseclibV2/UnableToConnectToSftpHost.php",
"chars": 599,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse League\\Flysystem\\FilesystemException;\nuse "
},
{
"path": "src/PhpseclibV2/UnableToEstablishAuthenticityOfHost.php",
"chars": 698,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse League\\Flysystem\\FilesystemException;\nuse "
},
{
"path": "src/PhpseclibV2/UnableToLoadPrivateKey.php",
"chars": 549,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV2;\n\nuse League\\Flysystem\\FilesystemException;\nuse "
},
{
"path": "src/PhpseclibV2/composer.json",
"chars": 646,
"preview": "{\n \"name\": \"league/flysystem-sftp\",\n \"description\": \"SFTP filesystem adapter for Flysystem.\",\n \"keywords\": [\"fl"
},
{
"path": "src/PhpseclibV3/.gitattributes",
"chars": 166,
"preview": "* text=auto\n\n.github export-ignore\n.gitattributes export-ignore\n.gitignore export-ignore\n**/*Test.php export-ignore\n**/*"
},
{
"path": "src/PhpseclibV3/.github/workflows/close-subsplit-prs.yaml",
"chars": 696,
"preview": "---\nname: Close sub-split PRs\n\non:\n push:\n branches:\n - 2.x\n - 3.x\n pull_request:\n branches:\n - 2"
},
{
"path": "src/PhpseclibV3/ConnectionProvider.php",
"chars": 217,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV3;\n\nuse phpseclib3\\Net\\SFTP;\n\n/**\n * @method void "
},
{
"path": "src/PhpseclibV3/ConnectivityChecker.php",
"chars": 191,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV3;\n\nuse phpseclib3\\Net\\SFTP;\n\ninterface Connectivi"
},
{
"path": "src/PhpseclibV3/FixatedConnectivityChecker.php",
"chars": 645,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV3;\n\nuse phpseclib3\\Net\\SFTP;\n\nclass FixatedConnect"
},
{
"path": "src/PhpseclibV3/LICENSE",
"chars": 1063,
"preview": "Copyright (c) 2013-2026 Frank de Jonge\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "src/PhpseclibV3/README.md",
"chars": 301,
"preview": "## Sub-split of Flysystem for SFTP using phpseclib v3.\n\n> ⚠️ this is a sub-split, for pull requests and issues, visit: h"
},
{
"path": "src/PhpseclibV3/SftpAdapter.php",
"chars": 12647,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV3;\n\nuse League\\Flysystem\\Config;\nuse League\\Flysys"
},
{
"path": "src/PhpseclibV3/SftpAdapterTest.php",
"chars": 7757,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV3;\n\nuse League\\Flysystem\\AdapterTestUtilities\\File"
},
{
"path": "src/PhpseclibV3/SftpConnectionProvider.php",
"chars": 6467,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace League\\Flysystem\\PhpseclibV3;\n\nuse League\\Flysystem\\FilesystemException;\nuse "
}
]
// ... and 93 more files (download for full content)
About this extraction
This page contains the full source code of the thephpleague/flysystem GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 293 files (720.5 KB), approximately 184.8k tokens, and a symbol index with 1627 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.