A stream wrapper for Flysystem V2.

Overview

Flysystem Stream Wrapper

Author Software License


This package provides a stream wrapper for Flysystem V2.

Flysystem V1

If you're looking for Flysystem 1.x support, check out the twistor/flysystem-stream-wrapper, on which this package is based on.

This project is a complete rewrite and has just the name and the functionality as stream wrapper in common with the V1 package. Please note that there is also a recent pull request for V2 waiting though the last merge seems to be from November 2018. Thus, a new package seemed to be reasonable.

Installation

composer require m2mtech/flysystem-stream-wrapper

Usage

use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
use M2MTech\FlysystemStreamWrapper\FlysystemStreamWrapper;

$filesystem = new Filesystem(new LocalFilesystemAdapter('/some/path'));
FlysystemStreamWrapper::register('fly', $filesystem);

file_put_contents('fly://filename.txt', $content);
mkdir('fly://happy_thoughts');

FlysystemStreamWrapper::unregister('fly');

Because locking is not supported by Flysystem V2, the stream wrapper implements symfony/lock. As default, it uses file locking using /tmp, which you can adjust via the configuration:

FlysystemStreamWrapper::register('fly', $filesystem, [
    FlysystemStreamWrapper::LOCK_STORE => 'flock:///tmp',
    FlysystemStreamWrapper::LOCK_TTL => 300,
]);

Testing

This package has been developed for php 7.4 with compatibility tested for php 7.2 to 8.0.

# with php installed
composer test

# or inside docker e.g. for php 7.4
docker-compose run php74 composer test

Changelog

Please see CHANGELOG for more information about recentl changes.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

Comments
  • `is_writable` returns false for created directories

    `is_writable` returns false for created directories

    I'm running into issues with the following code (minimal reproduction - my actual use case involves a third party lib)

    FlysystemStreamWrapper::register(
      "fly",
      new Filesystem(new LocalFilesystemAdapter("./")),
    );
    mkdir("fly://my-dir", 0666, true);
    is_writable("fly://my-dir");
    

    Expected is_writable should return true

    Actual is_writable returns false

    Research When a new directory is created inside the FlysystemStreamWrapper, it seems as if permissions are set to 755, meaning only the owner may write to the directory. Calling fileowner("fly://my-dir") returns 0 which is equivalent to the root user on my system - i.e. not my php user. This appears to cause php to believe it does not have write access to "my-dir".

    Forcing a write despite is_writable proves that the directory is, in fact, writable.

    Problems

    1. FlysystemStreamWrapper does not create directories with the requested access rights
    2. Created directories erroneously report owner 0
    bug enhancement 
    opened by FelixZY 6
  • visibility can still cause exceptions

    visibility can still cause exceptions

    To prevent the visibility problem there is a try catch around this operation

            try {
                $visibility = $current->filesystem->visibility($current->file);
            } catch (UnableToRetrieveMetadata $e) {
                if (!$current->ignoreVisibilityErrors()) {
                    throw $e;
                }
    
                $visibility = Visibility::PUBLIC;
            }
    

    in StreamStatCommand.php

    However, if the adapter just returns the default flysytems' FileAttributes object, which sets visiblity to null (as f.e. spaties dropboxadapter does, a bug in Flysystem will give a TypeError since the visibility function should not return null but a string (reported there). The TypeError is not caught by the above catch. It is probably a good idea to accept a wider range of throwables since any adapter may find their own way of letting know that visibility isn't a thing.

    opened by jurriaanr 3
  • is_readable is not working

    is_readable is not working

    We try to send E-Mails with Symfony's Mailer over async Messenger component.

    The App creates attachments and triggers the SendMailMessage. We use the flysystem-stream-wrapper to store those attachments on a secure S3 storage.

    It fails with Path [REDACTED] is not readable. in DataPart.php (Symfony Mailer Component) image

    Locally, it is somehow not a problem. So I thought it could have been something about the locking component, but changing the lock to in-memory and TTL to 1 second did not resolve the issue.

    So, I did a lot of debugging and printing and here are the results: image

    {
      attachment: {0}
      fileInfo: {}
      fileName: "[REDACTED]"
      isFile: true
      isReadable: false
      path: "gcloud://"
      pathInfo: {}
      pathname: "gcloud://[REDACTED]"
      realPath: false
      stat: {
        0: 0
        1: 0
        10: 1656327883
        11: -1
        12: -1
        2: 33152
        3: 0
        4: 0
        5: 65534
        6: 0
        7: 36798
        8: 1656327883
        9: 1656327883
        atime: 1656327883
        blksize: -1
        blocks: -1
        ctime: 1656327883
        dev: 0
        gid: 65534
        ino: 0
        mode: 33152
        mtime: 1656327883
        nlink: 0
        rdev: 0
        size: 36798
        uid: 0
      }
    }
    

    It seems to fail at is_readable, which returns false. So I tried to check the mode using stat, as I figured out with a bit of php source code reading that it seems to use that.

    Ignoring the is_readable, I tried to open the file to make sure the FlySystem is setup correctly: image

    And it actually works: image

    So the bug would seem to be, that the StreamStatCommand is not setting the right mode?

    bug enhancement 
    opened by CoalaJoe 3
  • fseek(): supplied resource is not a valid stream resource

    fseek(): supplied resource is not a valid stream resource

    image

    Currently on a migration and using this library. I need to fork it though and add the following line for it to work:

    StreamWrapper::109

                    if (is_resource($this->current->handle)) {
                        fseek($this->current->handle, $currentPosition);
                    }
    

    I don't know why this is needed there, but everything works fine afterwards. Maybe it is because the Stream is being rewinded after Flysystems writeStream. image

    image

    They also check weather or not the resource is seekable. That might be the right check.

    bug 
    opened by CoalaJoe 1
  • Update symplify/easy-coding-standard requirement from ^10.2 to ^10.2 || ^11.0

    Update symplify/easy-coding-standard requirement from ^10.2 to ^10.2 || ^11.0

    Updates the requirements on symplify/easy-coding-standard to permit the latest version.

    Commits
    • 452134a ECS 11.0.3
    • ad1f3dd Updated ECS to commit 6a31a05280c1a528009a9762a5ada587835aec1c
    • 522b725 Updated ECS to commit 8117340c0c29d2f83dfe24e748888c6f7748951d
    • a0b3ff3 Updated ECS to commit 6b0325a3b18c4b07a631540f3004ceefcfb4a3f7
    • 40e6d76 Updated ECS to commit 4c9ff1aaacda1285da4bd5e606233784b0e23811
    • eef28c6 ECS 11.0.2
    • 216faf9 Updated ECS to commit 4ac9399da67e02483aa593681de37b0aafac843c
    • 5fbc30e Updated ECS to commit dc3a521b654898daa23d7e26e2eac441291f1dac
    • 58fad33 Updated ECS to commit 6918cd0339f993b1d5ffe764f85666be0d9f3e65
    • f362aa4 Updated ECS to commit 6c3e89071d6d7cf76c1bede54e5edee192ede714
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Update symplify/easy-coding-standard requirement from 10.2.10 to 10.2.11

    Update symplify/easy-coding-standard requirement from 10.2.10 to 10.2.11

    Updates the requirements on symplify/easy-coding-standard to permit the latest version.

    Commits
    • 20899c6 ECS 10.2.11
    • b1c65dc Updated ECS to commit 87b14a0f6f07655c61a13fa0eb74a1418369e6d9
    • 386b719 Updated ECS to commit e16cb1b784b682f9dde17b51b754970957aed114
    • 76f5d30 Updated ECS to commit 9d1b0ea67bd15cdcbcf4177e76093c3d152f47f2
    • 664a6ec Updated ECS to commit b19e05864089b2a2b4076e1b058ff1ac8ce796b6
    • See full diff in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Update symplify/easy-coding-standard requirement from 10.2.7 to 10.2.10

    Update symplify/easy-coding-standard requirement from 10.2.7 to 10.2.10

    Updates the requirements on symplify/easy-coding-standard to permit the latest version.

    Commits
    • e68d4ea ECS 10.2.10
    • bad2dc8 Updated ECS to commit 2cc5f4a94d67863c59347cb5437c79f35782cb8b
    • 9068b5a Updated ECS to commit 4089451d7187546baa297b4e5c0e388032540547
    • be8b84a Updated ECS to commit dea90f61395a9adb96a604540ebbcc13b95c03d3
    • 916fb90 Updated ECS to commit 16497792a15fef84c963416dcfb8f3d62d94bee4
    • 1be370b Updated ECS to commit ac27dc64eacd24f375c56ec3f585cabe2d925859
    • e96bdff Updated ECS to commit 5c5cdc84c6b09a08744d485486222f4f82d0ed71
    • 3fd38ca Updated ECS to commit 159783a85d2011bd862933ca3eea52079ae784cd
    • 0fbacdc Updated ECS to commit 11e34b454e27505dd445e4f128d4ebc4e322bbdb
    • 6e0ea40 ECS 10.2.9
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Some adapters will close the stream themselves

    Some adapters will close the stream themselves

    When using the wrapper with https://github.com/thephpleague/flysystem-azure-blob-storage, the underlying adapter will take over handling the passed stream handle. It means that $this->current->handle could be closed when trying to fseek() and close it.

    opened by dkarlovi 0
Releases(v1.3.1)
Owner
Martin Mandl
Martin Mandl
Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel.

Laravel Flysystem Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel. It utilises my Larave

Graham Campbell 492 Feb 4, 2022
PHP Phar Stream Wrapper

Based on Sam Thomas' findings concerning insecure deserialization in combination with obfuscation strategies allowing to hide Phar files inside valid image resources, the TYPO3 project decided back then to introduce a PharStreamWrapper to intercept invocations of the phar:// stream in PHP and only allow usage for defined locations in the file system.

TYPO3 GitHub Department 55 Dec 7, 2022
Flysystem adapter for Google Cloud Storage

Flysystem adapter for Google Cloud Storage This package contains a Google Cloud Storage driver for Flysystem. Notice This package is a fork from super

Spatie 21 May 1, 2022
Flysystem V2 adapter for the webman

Flysystem V2 adapter for the webman

null 0 Nov 3, 2021
Microsoft OneDrive adapter for Flysystem 2+

Lexik Flysystem OneDrive Adapter This is a Flysystem 2+ adapter to interact with Microsoft OneDrive API. Setup In your Microsoft Azure portal create a

Choosit 3 Nov 19, 2021
💾 Flysystem adapter for the GitHub storage.

Flysystem Github Requirement PHP >= 7.2 CDN List 'github' => "https://raw.githubusercontent.com/:username/:repository/:branch/:fullfilename", 'fastg

wangzhiqiang 2 Mar 18, 2022
A Flysystem proxy adapter that enables compression and encryption of files and streams on the fly

Slam / flysystem-compress-and-encrypt-proxy Compress and Encrypt files and streams before saving them to the final Flysystem destination. Installation

Filippo Tessarotto 27 Jun 4, 2022
A stream wrapper for Flysystem V2.

Flysystem Stream Wrapper This package provides a stream wrapper for Flysystem V2. Flysystem V1 If you're looking for Flysystem 1.x support, check out

Martin Mandl 9 Oct 21, 2022
Laravel Flysystem - a Flysystem bridge for Laravel.

Laravel Flysystem Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel. It utilises my Larave

Graham Campbell 489 Dec 22, 2022
Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel.

Laravel Flysystem Laravel Flysystem was created by, and is maintained by Graham Campbell, and is a Flysystem bridge for Laravel. It utilises my Larave

Graham Campbell 492 Feb 4, 2022
A PHP Stream wrapper for Amazon S3

S3StreamWrapper A simple stream wrapper for Amazon S3. Example <?php use S3StreamWrapper\S3StreamWrapper; S3StreamWrapper::register(); $options = a

Gijs Kunze 21 Nov 23, 2021
vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with any unit test framework, like PHPUnit or SimpleTest.

vfsStream vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with

null 1.4k Dec 23, 2022
PHP Phar Stream Wrapper

Based on Sam Thomas' findings concerning insecure deserialization in combination with obfuscation strategies allowing to hide Phar files inside valid image resources, the TYPO3 project decided back then to introduce a PharStreamWrapper to intercept invocations of the phar:// stream in PHP and only allow usage for defined locations in the file system.

TYPO3 GitHub Department 55 Dec 7, 2022
Flysystem storage with local metadata storage for speed and manageability.

Laravel Filer This project was started to scratch my itch on our growing Laravel site: Metadata for all files is stored in a local repository - Suppor

Nick Vahalik 16 May 23, 2022
Flysystem adapter for Google Cloud Storage

Flysystem adapter for Google Cloud Storage This package contains a Google Cloud Storage driver for Flysystem. Notice This package is a fork from super

Spatie 21 May 1, 2022
Flysystem V2 adapter for the webman

Flysystem V2 adapter for the webman

null 0 Nov 3, 2021
Microsoft OneDrive adapter for Flysystem 2+

Lexik Flysystem OneDrive Adapter This is a Flysystem 2+ adapter to interact with Microsoft OneDrive API. Setup In your Microsoft Azure portal create a

Choosit 3 Nov 19, 2021
💾 Flysystem adapter for the GitHub storage.

Flysystem Github Requirement PHP >= 7.2 CDN List 'github' => "https://raw.githubusercontent.com/:username/:repository/:branch/:fullfilename", 'fastg

wangzhiqiang 2 Mar 18, 2022
A Flysystem proxy adapter that enables compression and encryption of files and streams on the fly

Slam / flysystem-compress-and-encrypt-proxy Compress and Encrypt files and streams before saving them to the final Flysystem destination. Installation

Filippo Tessarotto 27 Jun 4, 2022
This extension provides Flysystem integration for the Yii framework

This extension provides Flysystem integration for the Yii framework. Flysystem is a filesystem abstraction which allows you to easily swap out a local filesystem for a remote one.

Alexander Kochetov 276 Dec 9, 2022